]> gitweb.factorcode.org Git - factor.git/commitdiff
use bignum/f to get accurate division of fixnums >= 2^53 on 64-bit platforms
authorJoe Groff <arcata@gmail.com>
Sat, 31 Oct 2009 17:05:25 +0000 (12:05 -0500)
committerJoe Groff <arcata@gmail.com>
Sat, 31 Oct 2009 17:06:56 +0000 (12:06 -0500)
basis/hints/hints.factor
core/math/integers/integers-tests.factor
core/math/integers/integers.factor

index d7c745500bef196788a880917099e4dd046c6d15..1ca5bf1bc54ff898a1fec4d11b8c5be848f463cc 100644 (file)
@@ -3,8 +3,8 @@
 USING: accessors arrays assocs byte-arrays byte-vectors classes
 combinators definitions effects fry generic generic.single
 generic.standard hashtables io.binary io.streams.string kernel
-kernel.private math math.parser math.parser.private namespaces
-parser sbufs sequences splitting splitting.private strings
+kernel.private math math.integers.private math.parser math.parser.private
+namespaces parser sbufs sequences splitting splitting.private strings
 vectors words ;
 IN: hints
 
@@ -141,3 +141,4 @@ M\ hashtable set-at { { object fixnum object } { object word object } } "special
 
 \ string>integer { string fixnum } "specializer" set-word-prop
 
+\ bignum/f { { bignum bignum } { bignum fixnum } { fixnum bignum } { fixnum fixnum } } "specializer" set-word-prop
index a9469ae91a83c9dafb7606d05765d8b9fae631b3..76ce162d7d94f627ce9f7624f94fd8cb0047dd2d 100644 (file)
@@ -226,3 +226,6 @@ unit-test
         [ >float / ] [ /f ] 2bi 0.1 ~
     ] all?
 ] unit-test
+
+! Ensure that /f is accurate for fixnums > 2^53 on 64-bit platforms
+[ HEX: 1.758bec11492f9p-54 ] [ 1 12345678901234567 /f ] unit-test
index e684b8edfb479cf4c480f26d299eeee4f6a761f2..da8b8b9edc52b1dd13322c1b0131176db43007c1 100644 (file)
@@ -33,7 +33,16 @@ M: fixnum + fixnum+ ; inline
 M: fixnum - fixnum- ; inline
 M: fixnum * fixnum* ; inline
 M: fixnum /i fixnum/i ; inline
-M: fixnum /f [ >float ] dip >float float/f ; inline
+
+DEFER: bignum/f
+CONSTANT: bignum/f-threshold HEX: 20,0000,0000,0000
+
+: fixnum/f ( m n -- m/n )
+    [ >float ] bi@ float/f ; inline
+
+M: fixnum /f
+    2dup [ bignum/f-threshold >= ] either?
+    [ bignum/f ] [ fixnum/f ] if ; inline
 
 M: fixnum mod fixnum-mod ; inline
 
@@ -144,5 +153,8 @@ M: bignum (log2) bignum-log2 ; inline
         ] if-zero
     ] if ; inline
 
-M: bignum /f ( m n -- f )
+: bignum/f ( m n -- f )
     [ [ abs ] bi@ /f-abs ] [ [ 0 < ] bi@ xor ] 2bi [ neg ] when ;
+
+M: bignum /f ( m n -- f )
+    bignum/f ;