From cd459c68ec596fec4116ca35e755fb43229685e9 Mon Sep 17 00:00:00 2001 From: Pavel Panchekha Date: Sun, 18 Jan 2026 23:41:20 -0700 Subject: [PATCH 1/3] Faster flonum operations using flbit-field --- math-lib/math/private/flonum/flonum-bits.rkt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/math-lib/math/private/flonum/flonum-bits.rkt b/math-lib/math/private/flonum/flonum-bits.rkt index 691ed4b..ff5e6ba 100644 --- a/math-lib/math/private/flonum/flonum-bits.rkt +++ b/math-lib/math/private/flonum/flonum-bits.rkt @@ -12,8 +12,7 @@ (: flonum->bit-field (Flonum -> Natural)) (define (flonum->bit-field x) - (assert (integer-bytes->integer (real->floating-point-bytes x (ann 8 8)) #f) - exact-nonnegative-integer?)) + (flbit-field x 0 64)) (: bit-field->flonum (Integer -> Flonum)) (define (bit-field->flonum i) @@ -30,10 +29,9 @@ (: flonum->fields (Flonum -> (Values (U 0 1) Index Natural))) (define (flonum->fields x) - (define n (flonum->bit-field x)) - (values (if (zero? (bitwise-bit-field n 63 64)) 0 1) - (assert (bitwise-bit-field n 52 63) index?) - (bitwise-bit-field n 0 52))) + (values (if (zero? (flbit-field x 63 64)) 0 1) + (assert (flbit-field x 52 63) index?) + (flbit-field x 0 52))) (: fields->flonum (Integer Integer Integer -> Flonum)) (define (fields->flonum s e m) @@ -66,8 +64,8 @@ (: flonum->ordinal (Flonum -> Integer)) (define (flonum->ordinal x) - (cond [(x . fl< . 0.0) (- (flonum->bit-field (fl- 0.0 x)))] - [else (flonum->bit-field (flabs x))])) ; abs for -0.0 + (cond [(x . fl< . 0.0) (- (flbit-field (fl- 0.0 x) 0 64))] + [else (flbit-field (flabs x) 0 64)])) ; abs for -0.0 (: ordinal->flonum (Integer -> Flonum)) (define (ordinal->flonum i) From 898aa2fc95f67a5c8d329199367873fdd4fa13c9 Mon Sep 17 00:00:00 2001 From: Pavel Panchekha Date: Mon, 19 Jan 2026 13:49:37 -0700 Subject: [PATCH 2/3] Types --- math-lib/math/private/flonum/flonum-bits.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/math-lib/math/private/flonum/flonum-bits.rkt b/math-lib/math/private/flonum/flonum-bits.rkt index ff5e6ba..3f2fab0 100644 --- a/math-lib/math/private/flonum/flonum-bits.rkt +++ b/math-lib/math/private/flonum/flonum-bits.rkt @@ -2,6 +2,8 @@ (require racket/flonum racket/performance-hint) +(require/typed racket/flonum + [flbit-field (-> Flonum Byte Byte Natural)]) (provide flonum->bit-field bit-field->flonum flonum->fields fields->flonum From 197035e373e09ef5e568703c130c5db038a52c49 Mon Sep 17 00:00:00 2001 From: Pavel Panchekha Date: Mon, 19 Jan 2026 14:15:41 -0700 Subject: [PATCH 3/3] Faster flonums-between --- math-lib/math/private/flonum/flonum-bits.rkt | 18 ++++++++++++++---- math-test/math/tests/flonum-tests.rkt | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/math-lib/math/private/flonum/flonum-bits.rkt b/math-lib/math/private/flonum/flonum-bits.rkt index 3f2fab0..fc443ef 100644 --- a/math-lib/math/private/flonum/flonum-bits.rkt +++ b/math-lib/math/private/flonum/flonum-bits.rkt @@ -99,11 +99,21 @@ (: flprev (Flonum -> Flonum)) (define (flprev x) (flstep x -1)) - (: flonums-between (Flonum Flonum -> Integer)) - (define (flonums-between x y) - (- (flonum->ordinal y) (flonum->ordinal x))) - ) ; begin-encourage-inline + +(: flonum->chunks (-> Flonum (Values Integer Integer))) +(define (flonum->chunks x) + (define neg? (fl< x 0.0)) + (define ax (flabs x)) + (if neg? + (values (- (flbit-field ax 0 32)) (- (flbit-field ax 32 64))) + (values (flbit-field ax 0 32) (flbit-field ax 32 64)))) + +(: flonums-between (Flonum Flonum -> Integer)) +(define (flonums-between x y) + (define-values (xlo xhi) (flonum->chunks x)) + (define-values (ylo yhi) (flonum->chunks y)) + (+ (arithmetic-shift (- yhi xhi) 32) (- ylo xlo))) (: flulp (Flonum -> (U Flonum-Nan Nonnegative-Flonum))) (define (flulp x) diff --git a/math-test/math/tests/flonum-tests.rkt b/math-test/math/tests/flonum-tests.rkt index 9cc7277..9ac06f7 100644 --- a/math-test/math/tests/flonum-tests.rkt +++ b/math-test/math/tests/flonum-tests.rkt @@ -144,6 +144,12 @@ (check-equal? (flulp-error x (flnext x)) 1.0 (format "x = ~a" x))) +(for ([_ (in-range 1000)]) + (define x (ordinal->flonum (random-integer (flonum->ordinal -inf.0) (flonum->ordinal +inf.0)))) + (define y (ordinal->flonum (random-integer (flonum->ordinal -inf.0) (flonum->ordinal +inf.0)))) + (check-equal? (flonums-between x y) + (- (flonum->ordinal y) (flonum->ordinal x)))) + ;; =================================================================================================== ;; fllog2