diff --git a/collects/plot/plot3d/isosurface.rkt b/collects/plot/plot3d/isosurface.rkt index 1c4c33492f..c0a016a79c 100644 --- a/collects/plot/plot3d/isosurface.rkt +++ b/collects/plot/plot3d/isosurface.rkt @@ -178,13 +178,16 @@ (define 2pi (* 2 pi)) +(define (flmodulo x y) + (fl- x (fl* y (flfloor (fl/ x y))))) + (define ((2d-polar->3d-function f) x y z) (let ([x (exact->inexact x)] [y (exact->inexact y)] [z (exact->inexact z)]) (define-values (θ ρ) (cond [(and (fl= x 0.0) (fl= y 0.0)) (values 0.0 0.0)] - [else (values (flmodulo (flatan2 y x) 2pi) + [else (values (flmodulo (atan y x) 2pi) (flatan (fl/ z (fldistance x y))))])) (fl- (exact->inexact (f θ ρ)) (fldistance x y z)))) diff --git a/collects/plot/plot3d/plot-area.rkt b/collects/plot/plot3d/plot-area.rkt index 3660b1d395..91262e5da2 100644 --- a/collects/plot/plot3d/plot-area.rkt +++ b/collects/plot/plot3d/plot-area.rkt @@ -711,7 +711,7 @@ [else 1.0])) ;; Specular highlighting: Blinn-Phong model (define spec - (cond [specular-light? (fl* 32.0 (flexpt (flabs (vdot normal half-dir)) 20.0))] + (cond [specular-light? (fl* 32.0 (expt (flabs (vdot normal half-dir)) 20.0))] [else 0.0])) ;; Blend ambient light with diffuse light, return specular as it is ;; As ambient-light -> 1.0, contribution of diffuse -> 0.0 diff --git a/collects/unstable/flonum.rkt b/collects/unstable/flonum.rkt index 2359dbfdd9..0c91f95dcb 100644 --- a/collects/unstable/flonum.rkt +++ b/collects/unstable/flonum.rkt @@ -2,26 +2,11 @@ (require racket/unsafe/ops) -(provide flatan2 flmodulo flexpt - flonum->bit-field bit-field->flonum +(provide flonum->bit-field bit-field->flonum flonum->ordinal ordinal->flonum flstep flnext flprev - -max.0 -min.0 +min.0 +max.0) - -(define (flatan2 y x) - (cond [(not (flonum? y)) (raise-type-error 'flatan2 "flonum" 0 y x)] - [(not (flonum? x)) (raise-type-error 'flatan2 "flonum" 1 y x)] - [else (exact->inexact (atan y x))])) - -(define (flmodulo x y) - (cond [(not (flonum? x)) (raise-type-error 'flmodulo "flonum" 0 x y)] - [(not (flonum? y)) (raise-type-error 'flmodulo "flonum" 1 x y)] - [else (unsafe-fl- x (unsafe-fl* y (unsafe-flfloor (unsafe-fl/ x y))))])) - -(define (flexpt b x) - (cond [(not (flonum? b)) (raise-type-error 'flexpt "flonum" 0 b x)] - [(not (flonum? x)) (raise-type-error 'flexpt "flonum" 1 b x)] - [else (unsafe-flexp (unsafe-fl* x (unsafe-fllog b)))])) + -max.0 -min.0 +min.0 +max.0 + flonums-between) (define (flonum->bit-field x) (cond [(flonum? x) (integer-bytes->integer (real->floating-point-bytes x 8) #f)] @@ -67,3 +52,8 @@ (define -min.0 (flprev 0.0)) (define +min.0 (flnext 0.0)) (define +max.0 (flprev +inf.0)) + +(define (flonums-between x y) + (cond [(not (flonum? x)) (raise-type-error 'flonums-between "flonum" 0 x y)] + [(not (flonum? y)) (raise-type-error 'flonums-between "flonum" 1 x y)] + [else (- (flonum->ordinal y) (flonum->ordinal x))])) diff --git a/collects/unstable/scribblings/flonum.scrbl b/collects/unstable/scribblings/flonum.scrbl new file mode 100644 index 0000000000..700fe6e995 --- /dev/null +++ b/collects/unstable/scribblings/flonum.scrbl @@ -0,0 +1,105 @@ +#lang scribble/manual + +@(require scribble/eval + "utils.rkt" + (for-label racket unstable/flonum racket/flonum)) + +@(define the-eval (make-base-eval)) +@(the-eval '(require unstable/flonum + (rename-in (except-in plot plot plot3d) + [plot-bitmap plot] + [plot3d-bitmap plot3d]))) + +@title[#:tag "flonum"]{Flonums} +@unstable[@author+email["Neil Toronto" "ntoronto@racket-lang.org"]] + +@defmodule[unstable/flonum] + + + +@defproc[(flonum->bit-field [x flonum?]) (integer-in 0 (- (expt 2 64) 1))]{ +Returns the bits comprising @racket[x] as an integer. +A convenient shortcut for composing @racket[integer-bytes->integer] with @racket[real->floating-point-bytes]. +@examples[#:eval the-eval + (number->string (flonum->bit-field -inf.0) 16) + (number->string (flonum->bit-field +inf.0) 16) + (number->string (flonum->bit-field -0.0) 16) + (number->string (flonum->bit-field 0.0) 16) + (number->string (flonum->bit-field -1.0) 16) + (number->string (flonum->bit-field 1.0) 16) + (number->string (flonum->bit-field +nan.0) 16)] +} + +@defproc[(bit-field->flonum [i (integer-in 0 (- (expt 2 64) 1))]) flonum?]{ +The inverse of @racket[flonum->bit-field]. +} + +@defproc[(flonum->ordinal [x flonum?]) (integer-in (- (- (expt 2 63) 1)) (- (expt 2 63) 1))]{ +Returns the signed ordinal index of @racket[x] in a total order over flonums. + +When inputs are not @racket[+nan.0], this function is monotone and symmetric; +i.e. if @racket[(fl<= x y)] then @racket[(<= (flonum->ordinal x) (flonum->ordinal y))], +and @racket[(= (flonum->ordinal (- x)) (- (flonum->ordinal x)))]. +@examples[#:eval the-eval + (flonum->ordinal -inf.0) + (flonum->ordinal +inf.0) + (flonum->ordinal -0.0) + (flonum->ordinal 0.0) + (flonum->ordinal -1.0) + (flonum->ordinal 1.0) + (flonum->ordinal +nan.0)] +These properties mean that @racket[flonum->ordinal] does not distinguish @racket[-0.0] and @racket[0.0]. + +The following plot demonstrates how the density of floating-point numbers decreases with magnitude: +@examples[#:eval the-eval + (parameterize ([y-axis-ticks? #f]) + (plot (list (function (compose flonum->ordinal exact->inexact) 1/4 8) + (y-axis 1/2) (y-axis 1) (y-axis 2) (y-axis 4))))] +} + +@defproc[(ordinal->flonum [i (integer-in (- (- (expt 2 63) 1)) (- (expt 2 63) 1))]) flonum?]{ +The inverse of @racket[flonum->ordinal]. +} + +@defproc[(flonums-between [x flonum?] [y flonum?]) exact-integer?]{ +Returns the number of flonums between @racket[x] and @racket[y], excluding one endpoint. +Equivalent to @racket[(- (flonum->ordinal y) (flonum->ordinal x))]. +@examples[#:eval the-eval + (flonums-between 0.0 1.0) + (flonums-between 1.0 2.0) + (flonums-between 2.0 3.0) + (flonums-between 1.0 +inf.0)] +} + +@defproc[(flstep [x flonum?] [n exact-integer?]) flonum?]{ +Returns the flonum @racket[n] flonums away from @racket[x], according to @racket[flonum->ordinal]. If @racket[x] is @racket[+nan.0], returns @racket[+nan.0]. +@examples[#:eval the-eval + (flstep 0.0 1) + (flstep (flstep 0.0 1) -1) + (flstep 0.0 -1) + (flstep +inf.0 1) + (flstep +inf.0 -1) + (flstep -inf.0 -1) + (flstep -inf.0 1) + (flstep +nan.0 1000)] +} + +@defproc[(flnext [x flonum?]) flonum?]{ +Equivalent to @racket[(flstep x 1)]. +} + +@defproc[(flprev [x flonum?]) flonum?]{ +Equivalent to @racket[(flstep x -1)]. +} + +@deftogether[(@defthing[-max.0 flonum?] + @defthing[-min.0 flonum?] + @defthing[+min.0 flonum?] + @defthing[+max.0 flonum?])]{ +The rational flonums with maximum and minimum magnitude. +@examples[#:eval the-eval + (list -max.0 +max.0 -min.0 +min.0) + (plot (function sqrt 0 (* 20 +min.0)))] +} + +@(close-eval the-eval) diff --git a/collects/unstable/scribblings/unstable.scrbl b/collects/unstable/scribblings/unstable.scrbl index f0b1da2385..76b87e07c8 100644 --- a/collects/unstable/scribblings/unstable.scrbl +++ b/collects/unstable/scribblings/unstable.scrbl @@ -82,6 +82,7 @@ Keep documentation and tests up to date. @include-section["define.scrbl"] @include-section["file.scrbl"] @include-section["find.scrbl"] +@include-section["flonum.scrbl"] @include-section["future.scrbl"] @include-section["function.scrbl"] @include-section["generics.scrbl"]