math.functions: implement "frexp" and support log of really big numbers. Fixes #160.
parent
fa52349f9c
commit
077ef8ed5b
|
@ -110,6 +110,10 @@ HELP: exp
|
|||
{ $values { "x" number } { "y" number } }
|
||||
{ $description "Exponential function, " { $snippet "y=e^x" } "." } ;
|
||||
|
||||
HELP: frexp
|
||||
{ $values { "x" number } { "y" float } { "exp" integer } }
|
||||
{ $description "Break the number " { $snippet "x" } " into a normalized fraction " { $snippet "y" } " and an integral power of 2 " { $snippet "exp" } "." $nl "The function returns a number " { $snippet "y" } " in the interval [1/2, 1) or 0, and a number " { $snippet "exp" } " such that " { $snippet "x = y*(2**exp)" } "." } ;
|
||||
|
||||
HELP: log
|
||||
{ $values { "x" number } { "y" number } }
|
||||
{ $description "Natural logarithm function. Outputs negative infinity if " { $snippet "x" } " is 0." } ;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
USING: kernel math math.constants math.functions math.order
|
||||
math.private math.libm tools.test ;
|
||||
USING: kernel math math.constants math.functions math.libm
|
||||
math.order math.ranges math.private sequences tools.test ;
|
||||
|
||||
IN: math.functions.tests
|
||||
|
||||
[ t ] [ 4 4 .00000001 ~ ] unit-test
|
||||
|
@ -37,15 +38,33 @@ IN: math.functions.tests
|
|||
[ 0 ] [ 0 3.0 ^ ] unit-test
|
||||
[ 0 ] [ 0 3 ^ ] unit-test
|
||||
|
||||
: factorial ( n -- n! ) [ 1 ] [ [1,b] 1 [ * ] reduce ] if-zero ;
|
||||
|
||||
[ 0.0 0 ] [ 0 frexp ] unit-test
|
||||
[ 0.5 1 ] [ 1 frexp ] unit-test
|
||||
[ -0.5 1 ] [ -1 frexp ] unit-test
|
||||
[ 0.5 2 ] [ 2 frexp ] unit-test
|
||||
[ -0.5 2 ] [ -2 frexp ] unit-test
|
||||
[ 0.64 -6 ] [ 0.01 frexp ] unit-test
|
||||
[ -0.64 -6 ] [ -0.01 frexp ] unit-test
|
||||
[ 0.75 0 ] [ 0.75 frexp ] unit-test
|
||||
[ -0.75 0 ] [ -0.75 frexp ] unit-test
|
||||
[ 1/0. 0 ] [ 1/0. frexp ] unit-test
|
||||
[ -1/0. 0 ] [ -1/0. frexp ] unit-test
|
||||
[ 0.6588418960767314 8530 t ] [ 1000 factorial [ frexp ] [ bignum? ] bi ] unit-test
|
||||
[ -0.6588418960767314 8530 t ] [ 1000 factorial neg [ frexp ] [ bignum? ] bi ] unit-test
|
||||
|
||||
[ 0.0 ] [ 1 log ] unit-test
|
||||
[ 0.0 ] [ 1.0 log ] unit-test
|
||||
[ 1.0 ] [ e log ] unit-test
|
||||
[ 5912.128178488163 t ] [ 1000 factorial [ log ] [ bignum? ] bi ] unit-test
|
||||
|
||||
[ 0.0 ] [ 1.0 log10 ] unit-test
|
||||
[ 1.0 ] [ 10.0 log10 ] unit-test
|
||||
[ 2.0 ] [ 100.0 log10 ] unit-test
|
||||
[ 3.0 ] [ 1000.0 log10 ] unit-test
|
||||
[ 4.0 ] [ 10000.0 log10 ] unit-test
|
||||
[ 2567.604644222133 t ] [ 1000 factorial [ log10 ] [ bignum? ] bi ] unit-test
|
||||
|
||||
[ t ] [ 1 exp e 1.e-10 ~ ] unit-test
|
||||
[ f ] [ 1 exp 0/0. 1.e-10 ~ ] unit-test
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
! Copyright (C) 2004, 2010 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: math kernel math.constants math.private math.bits
|
||||
math.libm combinators fry math.order sequences ;
|
||||
math.libm combinators fry math.order sequences
|
||||
combinators.short-circuit math.bitwise ;
|
||||
IN: math.functions
|
||||
|
||||
: >fraction ( a/b -- a b )
|
||||
|
@ -155,6 +156,23 @@ M: real absq sq ; inline
|
|||
: >=1? ( x -- ? )
|
||||
dup complex? [ drop f ] [ 1 >= ] if ; inline
|
||||
|
||||
GENERIC: frexp ( x -- y exp )
|
||||
|
||||
M: float frexp
|
||||
dup { [ fp-special? ] [ zero? ] } 1|| [ 0 ] [
|
||||
double>bits
|
||||
[ HEX: 800f,ffff,ffff,ffff bitand 0.5 double>bits bitor bits>double ]
|
||||
[ -52 shift 11 on-bits bitand 1022 - ] bi
|
||||
] if ; inline
|
||||
|
||||
M: integer frexp
|
||||
[ 0.0 0 ] [
|
||||
dup 0 > [ 1 ] [ abs -1 ] if swap dup log2 [
|
||||
52 swap - shift 52 on-bits bitand
|
||||
0.5 double>bits bitor bits>double
|
||||
] [ 1 + ] bi [ * ] dip
|
||||
] if-zero ; inline
|
||||
|
||||
GENERIC: log ( x -- y )
|
||||
|
||||
M: float log dup 0.0 >= [ flog ] [ 0.0 rect> log ] if ; inline
|
||||
|
@ -163,6 +181,24 @@ M: real log >float log ; inline
|
|||
|
||||
M: complex log >polar [ flog ] dip rect> ; inline
|
||||
|
||||
<PRIVATE
|
||||
|
||||
CONSTANT: most-positive-finite-float $[ 1/0. prev-float >integer ]
|
||||
CONSTANT: most-negative-finite-float $[ -1/0. next-float >integer ]
|
||||
|
||||
MACRO: bignum-loghelper ( quot: ( x -- y ) -- quot )
|
||||
dup 2 over call( x -- y ) '[
|
||||
dup
|
||||
most-positive-finite-float
|
||||
most-negative-finite-float
|
||||
between?
|
||||
[ >float @ ] [ frexp [ @ ] [ _ * ] bi* + ] if
|
||||
] ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
M: bignum log [ log ] bignum-loghelper ;
|
||||
|
||||
GENERIC: log1+ ( x -- y )
|
||||
|
||||
M: object log1+ 1 + log ; inline
|
||||
|
@ -177,6 +213,8 @@ M: real log10 >float flog10 ; inline
|
|||
|
||||
M: complex log10 log 10 log / ; inline
|
||||
|
||||
M: bignum log10 [ log10 ] bignum-loghelper ;
|
||||
|
||||
GENERIC: cos ( x -- y ) foldable
|
||||
|
||||
M: complex cos
|
||||
|
|
Loading…
Reference in New Issue