]> gitweb.factorcode.org Git - factor.git/commitdiff
math.ratios: moving to core.
authorJohn Benediktsson <mrjbq7@gmail.com>
Thu, 30 Jul 2015 16:41:58 +0000 (09:41 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Thu, 30 Jul 2015 17:31:00 +0000 (10:31 -0700)
18 files changed:
basis/debugger/debugger.factor
basis/math/functions/functions-docs.factor
basis/math/functions/functions-tests.factor
basis/math/functions/functions.factor
basis/math/ratios/authors.txt [deleted file]
basis/math/ratios/ratios-docs.factor [deleted file]
basis/math/ratios/ratios-tests.factor [deleted file]
basis/math/ratios/ratios.factor [deleted file]
basis/math/ratios/summary.txt [deleted file]
core/bootstrap/stage1.factor
core/math/math-docs.factor
core/math/math-tests.factor
core/math/math.factor
core/math/ratios/authors.txt [new file with mode: 0644]
core/math/ratios/ratios-docs.factor [new file with mode: 0644]
core/math/ratios/ratios-tests.factor [new file with mode: 0644]
core/math/ratios/ratios.factor [new file with mode: 0644]
core/math/ratios/summary.txt [new file with mode: 0644]

index bac63016eeaa9844e237c7ebba69361e34d5d042..2fe87b4b8f14c145a98046442c64a26e3a4c7eaa 100755 (executable)
@@ -6,10 +6,11 @@ combinators combinators.short-circuit compiler.errors
 compiler.units continuations definitions destructors
 effects.parser fry generic generic.math generic.parser
 generic.single grouping io io.encodings io.styles kernel
-kernel.private lexer make math math.order math.parser namespaces
-parser prettyprint sequences sequences.private slots
-source-files.errors strings strings.parser summary system vocabs
-vocabs.loader vocabs.parser words ;
+kernel.private lexer make math math.order math.parser
+math.ratios namespaces parser prettyprint sequences
+sequences.private slots source-files.errors strings
+strings.parser summary system vocabs vocabs.loader vocabs.parser
+words ;
 FROM: namespaces => change-global ;
 IN: debugger
 
@@ -190,6 +191,9 @@ M: vm-error error. dup vm-errors dispatch ;
 
 M: vm-error error-help vm-errors nth first ;
 
+M: division-by-zero summary
+    drop "Division by zero" ;
+
 M: no-method summary
     drop "No suitable method" ;
 
index 32efeaa52c019c115dec3090317cce8cdbcbc814..146204db0ee27848c8f1a77fcf6332a6b9f36ed9 100644 (file)
@@ -95,14 +95,6 @@ ARTICLE: "math-functions" "Mathematical functions"
 
 ABOUT: "math-functions"
 
-HELP: rect>
-{ $values { "x" real } { "y" real } { "z" number } }
-{ $description "Creates a complex number from real and imaginary components. If " { $snippet "z" } " is an integer zero, this will simply output " { $snippet "x" } "." } ;
-
-HELP: >rect
-{ $values { "z" number } { "x" real } { "y" real } }
-{ $description "Extracts the real and imaginary components of a complex number." } ;
-
 HELP: align
 { $values { "m" integer } { "w" "a power of 2" } { "n" "an integer multiple of " { $snippet "w" } } }
 { $description "Outputs the least multiple of " { $snippet "w" } " greater than " { $snippet "m" } "." }
@@ -280,11 +272,6 @@ HELP: 10^
 { $values { "x" number } { "y" number } }
 { $description "Raises 10 to the power of " { $snippet "x" } ". If " { $snippet "x" } " is an integer the answer is computed exactly, otherwise a floating point approximation is used." } ;
 
-HELP: gcd
-{ $values { "x" integer } { "y" integer } { "a" integer } { "d" integer } }
-{ $description "Computes the positive greatest common divisor " { $snippet "d" } " of " { $snippet "x" } " and " { $snippet "y" } ", and another value " { $snippet "a" } " satisfying:" { $code "a*y = d mod x" } }
-{ $notes "If " { $snippet "d" } " is 1, then " { $snippet "a" } " is the inverse of " { $snippet "y" } " modulo " { $snippet "x" } "." } ;
-
 HELP: divisor?
 { $values { "m" integer } { "n" integer } { "?" boolean } }
 { $description "Tests if " { $snippet "n" } " is a divisor of " { $snippet "m" } ". This is the same thing as asking if " { $snippet "m" } " is divisible by " { $snippet "n" } "." }
index b772c1aa0db0d75c965bcfe25a9737ac11ea0738..0dec2a73451c28673ea2959779a1a8930cf24c31 100644 (file)
@@ -127,56 +127,6 @@ CONSTANT: log10-factorial-1000 0x1.40f3593ed6f8ep11
 { t } [ 10 atanh tanh 10 1.e-10 ~ ] unit-test
 { t } [ 0.5 atanh tanh 0.5 1.e-10 ~ ] unit-test
 
-{ 100 } [ 100 100 gcd nip ] unit-test
-{ 100 } [ 1000 100 gcd nip ] unit-test
-{ 100 } [ 100 1000 gcd nip ] unit-test
-{ 4 } [ 132 64 gcd nip ] unit-test
-{ 4 } [ -132 64 gcd nip ] unit-test
-{ 4 } [ -132 -64 gcd nip ] unit-test
-{ 4 } [ 132 -64 gcd nip ] unit-test
-{ 4 } [ -132 -64 gcd nip ] unit-test
-
-{ 100 } [ 100 >bignum 100 >bignum gcd nip ] unit-test
-{ 100 } [ 1000 >bignum 100 >bignum gcd nip ] unit-test
-{ 100 } [ 100 >bignum 1000 >bignum gcd nip ] unit-test
-{ 4 } [ 132 >bignum 64 >bignum gcd nip ] unit-test
-{ 4 } [ -132 >bignum 64 >bignum gcd nip ] unit-test
-{ 4 } [ -132 >bignum -64 >bignum gcd nip ] unit-test
-{ 4 } [ 132 >bignum -64 >bignum gcd nip ] unit-test
-{ 4 } [ -132 >bignum -64 >bignum gcd nip ] unit-test
-
-{ 6 } [
-    1326264299060955293181542400000006
-    1591517158873146351817850880000000
-    gcd nip
-] unit-test
-
-{ 11 } [
-    13262642990609552931815424
-    159151715887314635181785
-    gcd nip
-] unit-test
-
-{ 3 } [
-    13262642990609552931
-    1591517158873146351
-    gcd nip
-] unit-test
-
-{ 26525285981219 } [
-    132626429906095
-    159151715887314
-    gcd nip
-] unit-test
-
-
-: verify-gcd ( a b -- ? )
-    2dup gcd
-    [ rot * swap rem ] dip = ;
-
-{ t } [ 123 124 verify-gcd ] unit-test
-{ t } [ 50 120 verify-gcd ] unit-test
-
 { t } [ 0 42 divisor? ] unit-test
 { t } [ 42 7 divisor? ] unit-test
 { t } [ 42 -7 divisor? ] unit-test
index 6b1382fa1a2c086f252f499d767ea0857ce8f53e..22e07db9844cb13a90636e87696d691e9133b2c4 100644 (file)
@@ -4,10 +4,6 @@ USING: math kernel math.constants math.private math.bits
 math.libm combinators fry math.order sequences ;
 IN: math.functions
 
-: rect> ( x y -- z )
-    ! Note: an imaginary 0.0 should still create a complex
-    dup 0 = [ drop ] [ complex boa ] if ; inline
-
 GENERIC: sqrt ( x -- y ) foldable
 
 M: real sqrt
@@ -55,12 +51,6 @@ M: complex ^n (^n) ;
 
 PRIVATE>
 
-GENERIC: >rect ( z -- x y )
-
-M: real >rect 0 ; inline
-
-M: complex >rect [ real-part ] [ imaginary-part ] bi ; inline
-
 : >float-rect ( z -- x y )
     >rect [ >float ] bi@ ; inline
 
@@ -103,13 +93,6 @@ M: complex e^ >rect [ e^ ] dip polar> ; inline
     [ make-bits 1 ] dip dup
     '[ [ over * _ mod ] when [ sq _ mod ] dip ] reduce nip ; inline
 
-: (gcd) ( b a x y -- a d )
-    swap [
-        nip
-    ] [
-        [ /mod [ over * swapd - ] dip ] keep (gcd)
-    ] if-zero ; inline recursive
-
 PRIVATE>
 
 : ^ ( x y -- z )
@@ -122,21 +105,6 @@ PRIVATE>
 
 : nth-root ( n x -- y ) swap recip ^ ; inline
 
-: gcd ( x y -- a d )
-    [ 0 1 ] 2dip (gcd) dup 0 < [ neg ] when ; inline
-
-MATH: fast-gcd ( x y -- d ) foldable
-
-<PRIVATE
-
-: simple-gcd ( x y -- d ) gcd nip ; inline
-
-PRIVATE>
-
-M: real fast-gcd simple-gcd ; inline
-
-M: bignum fast-gcd bignum-gcd ; inline
-
 : lcm ( a b -- c )
     [ * ] 2keep fast-gcd /i ; foldable
 
diff --git a/basis/math/ratios/authors.txt b/basis/math/ratios/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/math/ratios/ratios-docs.factor b/basis/math/ratios/ratios-docs.factor
deleted file mode 100644 (file)
index 57b37f1..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-USING: help.markup help.syntax math math.private
-math.ratios.private math.functions ;
-IN: math.ratios
-
-ARTICLE: "rationals" "Rational numbers"
-{ $subsections ratio }
-"When we add, subtract or multiply any two integers, the result is always an integer. However, dividing a numerator by a denominator that is not an integral divisor of the denominator yields a ratio:"
-{ $example "1210 11 / ." "110" }
-{ $example "100 330 / ." "10/33" }
-{ $example "14 10 / ." "1+2/5" }
-"Ratios are printed and can be input literally in the form above. Ratios are always reduced to lowest terms by factoring out the greatest common divisor of the numerator and denominator. A ratio with a denominator of 1 becomes an integer. Division with a denominator of 0 throws an error."
-$nl
-"Ratios behave just like any other number -- all numerical operations work as you would expect."
-{ $example "1/2 1/3 + ." "5/6" }
-{ $example "100 6 / 3 * ." "50" }
-"Ratios can be taken apart:"
-{ $subsections
-    numerator
-    denominator
-    >fraction
-}
-{ $see-also "syntax-ratios" } ;
-
-ABOUT: "rationals"
-
-HELP: ratio
-{ $class-description "The class of rational numbers with denominator not equal to 1." } ;
-
-HELP: rational
-{ $class-description "The class of rational numbers, a disjoint union of integers and ratios." } ;
-
-HELP: numerator
-{ $values { "a/b" rational } { "a" integer } }
-{ $description "Outputs the numerator of a rational number. Acts as the identity on integers." } ;
-
-HELP: denominator
-{ $values { "a/b" rational } { "b" "a positive integer" } }
-{ $description "Outputs the denominator of a rational number. Always outputs 1 with integers." } ;
-
-HELP: fraction>
-{ $values { "a" integer } { "b" "a positive integer" } { "a/b" rational } }
-{ $description "Creates a new ratio, or outputs the numerator if the denominator is 1. This word does not reduce the fraction to lowest terms, and should not be called directly; use " { $link / } " instead." } ;
-
-HELP: >fraction
-{ $values { "a/b" rational } { "a" integer } { "b" "a positive integer" } }
-{ $description "Extracts the numerator and denominator of a rational number." } ;
-
-HELP: 2>fraction
-{ $values { "a/b" rational } { "c/d" rational } { "a" integer } { "c" integer } { "b" "a positive integer" } { "d" "a positive integer" } }
-{ $description "Extracts the numerator and denominator of two rational numbers at once." } ;
diff --git a/basis/math/ratios/ratios-tests.factor b/basis/math/ratios/ratios-tests.factor
deleted file mode 100644 (file)
index 0b44e95..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-USING: kernel math math.order math.parser math.ratios
-math.functions tools.test ;
-IN: math.ratios.tests
-
-{ 1 2 } [ 1/2 >fraction ] unit-test
-
-{ 1/2 } [ 1 >bignum 2 >bignum / ] unit-test
-{ t } [ 10 3 / ratio? ] unit-test
-{ f } [ 10 2 / ratio? ] unit-test
-{ 10 } [ 10 numerator ] unit-test
-{ 1 } [ 10 denominator ] unit-test
-{ 12 } [ -12 -13 / numerator ] unit-test
-{ 13 } [ -12 -13 / denominator ] unit-test
-{ 1 } [ -1 -1 / numerator ] unit-test
-{ 1 } [ -1 -1 / denominator ] unit-test
-
-{ -1 } [ 2 -2 / ] unit-test
-{ -1 } [ -2 2 / ] unit-test
-
-{ t } [ 1 3 / 1 3 / = ] unit-test
-
-{ -10 } [ -100 10 /i ] unit-test
-{ 10 } [ -100 -10 /i ] unit-test
-{ -10 } [ 100 -10 /i ] unit-test
-{ -10 } [ -100 >bignum 10 >bignum /i ] unit-test
-{ 10  } [ -100 >bignum -10 >bignum /i ] unit-test
-{ -10 } [ 100 >bignum -10 >bignum /i ] unit-test
-
-{ 3/2 } [ 1 1/2 + ] unit-test
-{ 3/2 } [ 1 >bignum 1/2 + ] unit-test
-{ -1/2 } [ 1/2 1 - ] unit-test
-{ -1/2 } [ 1/2 1 >bignum - ] unit-test
-{ 41/20 } [ 5/4 4/5 + ] unit-test
-
-{ 1 } [ 1/2 2 * ] unit-test
-{ 1/3 } [ 1/2 2/3 * ] unit-test
-
-{ 1 } [ 1/2 1/2 / ] unit-test
-{ 27/4 } [ 3/2 2/9 / ] unit-test
-
-{ t } [ 5768 476343 < ] unit-test
-{ t } [ 5768 476343 <= ] unit-test
-{ f } [ 5768 476343 > ] unit-test
-{ f } [ 5768 476343 >= ] unit-test
-{ t } [ 3434 >bignum 3434 >= ] unit-test
-{ t } [ 3434 3434 >bignum <= ] unit-test
-
-{ t } [ 1 1/3 > ] unit-test
-{ t } [ 2/3 3/4 <= ] unit-test
-{ f } [ -2/3 1/3 > ] unit-test
-
-{ t } [ 1000000000/999999 1000 > ] unit-test
-{ f } [ 100000 100000000000/999999 > ] unit-test
-{ t }
-[ 1000000000000/999999999999 1000000000001/999999999998 < ]
-unit-test
-
-{ -3 } [ -3 10 mod ] unit-test
-{ 7 } [ -3 10 rem ] unit-test
-{ 7 } [ -13 10 rem ] unit-test
-{ 0 } [ 37 37 rem ] unit-test
-
-{ -1 } [ -12.55 sgn ] unit-test
-{ 1 } [ 100000000000000000000000000000000 sgn ] unit-test
-{ 0 } [ 0.0 sgn ] unit-test
-
-{ 1/2 } [ 1/2 1 mod ] unit-test
-{ 1/3 } [ 10/3 3 mod ] unit-test
-{ -1/3 } [ -10/3 3 mod ] unit-test
-
-{ 4 1/2 } [ 3+1/2 3/4 /mod ] unit-test
-{ -4 -1/2 } [ -3-1/2 3/4 /mod ] unit-test
-{ 4 -1/2 } [ -3-1/2 -3/4 /mod ] unit-test
-{ -4 1/2 } [ 3+1/2 -3/4 /mod ] unit-test
-
-{ 5 } [ 5 floor ] unit-test
-{ -5 } [ -5 floor ] unit-test
-{ 6 } [ 6 truncate ] unit-test
-{ 3 } [ 10/3 floor ] unit-test
-{ -4 } [ -10/3 floor ] unit-test
-{ 4 } [ 10/3 ceiling ] unit-test
-{ -3 } [ -10/3 ceiling ] unit-test
-{ 3 } [ 10/3 truncate ] unit-test
-{ -3 } [ -10/3 truncate ] unit-test
-
-{ -1/2 } [ 1/2 1 - ] unit-test
-{ 3/2 } [ 1/2 1 + ] unit-test
-
-{ 1.0 } [ 0.5 1/2 + ] unit-test
-{ 1.0 } [ 1/2 0.5 + ] unit-test
-
-{ 1/134217728 } [ -1 -134217728 >fixnum / ] unit-test
-{ 134217728 } [ -134217728 >fixnum -1 / ] unit-test
-
-{ 5 }
-[ "10/2" string>number ]
-unit-test
-
-{ -5 }
-[ "-10/2" string>number ]
-unit-test
-
-{ f }
-[ "10/-2" string>number ]
-unit-test
-
-{ f }
-[ "-10/-2" string>number ]
-unit-test
-
-{ "33/100" }
-[ "66/200" string>number number>string ]
-unit-test
-
-{ 3 } [ "1+1/2" string>number 2 * ] unit-test
-{ -3 } [ "-1-1/2" string>number 2 * ] unit-test
-{ "2+1/7" } [ 1 7 / 2 + number>string ] unit-test
-{ "1/8" } [ 1 8 / number>string ] unit-test
-
-{ t } [ 2/3 dup number= ] unit-test
-{ t } [ 2/33333333333333333333333333333333 dup number= ] unit-test
-{ t } [ -2/3 dup number= ] unit-test
-{ t } [ -2/33333333333333333333333333333333 dup number= ] unit-test
diff --git a/basis/math/ratios/ratios.factor b/basis/math/ratios/ratios.factor
deleted file mode 100644 (file)
index 5d693ec..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel kernel.private math math.functions
-math.private sequences summary ;
-IN: math.ratios
-
-: 2>fraction ( a/b c/d -- a c b d )
-    [ >fraction ] bi@ swapd ; inline
-
-<PRIVATE
-
-: fraction> ( a b -- a/b )
-    dup 1 number= [ drop ] [ ratio boa ] if ; inline
-
-: (scale) ( a b c d -- a*d b*c )
-    [ * swap ] dip * swap ; inline
-
-: scale ( a/b c/d -- a*d b*c )
-    2>fraction (scale) ; inline
-
-: scale+d ( a/b c/d -- a*d b*c b*d )
-    2>fraction [ (scale) ] 2keep * ; inline
-
-PRIVATE>
-
-ERROR: division-by-zero x ;
-
-M: division-by-zero summary
-    drop "Division by zero" ;
-
-M: integer /
-    [
-        division-by-zero
-    ] [
-        dup 0 < [ [ neg ] bi@ ] when
-        2dup fast-gcd [ /i ] curry bi@ fraction>
-    ] if-zero ;
-
-M: integer recip
-    1 swap [
-        division-by-zero
-    ] [
-        dup 0 < [ [ neg ] bi@ ] when fraction>
-    ] if-zero ;
-
-M: ratio recip
-    >fraction swap dup 0 < [ [ neg ] bi@ ] when fraction> ;
-
-M: ratio hashcode*
-    nip >fraction [ hashcode ] bi@ bitxor ;
-
-M: ratio equal?
-    over ratio? [
-        2>fraction = [ = ] [ 2drop f ] if
-    ] [ 2drop f ] if ;
-
-M: ratio number=
-    2>fraction number= [ number= ] [ 2drop f ] if ;
-
-M: ratio >fixnum >fraction /i >fixnum ;
-M: ratio >bignum >fraction /i >bignum ;
-M: ratio >float >fraction /f ;
-
-M: ratio numerator numerator>> ; inline
-M: ratio denominator denominator>> ; inline
-M: ratio >fraction [ numerator ] [ denominator ] bi ; inline
-
-M: ratio < scale < ;
-M: ratio <= scale <= ;
-M: ratio > scale > ;
-M: ratio >= scale >= ;
-
-M: ratio + scale+d [ + ] [ / ] bi* ;
-M: ratio - scale+d [ - ] [ / ] bi* ;
-M: ratio * 2>fraction [ * ] 2bi@ / ;
-M: ratio / scale / ;
-M: ratio /i scale /i ;
-M: ratio /f scale /f ;
-M: ratio mod scale+d [ mod ] [ / ] bi* ;
-M: ratio /mod scale+d [ /mod ] [ / ] bi* ;
-M: ratio abs dup neg? [ >fraction [ neg ] dip fraction> ] when ;
-M: ratio neg? numerator neg? ; inline
diff --git a/basis/math/ratios/summary.txt b/basis/math/ratios/summary.txt
deleted file mode 100644 (file)
index 6077e3d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Rational number implementation
index 589378a309aa067872fb801235054f70a998430b..fd176d1376fcf13d8cc03eb20adcbe94e94c2dff 100644 (file)
@@ -28,6 +28,7 @@ load-help? off
     ] %
 
     "math.integers" require
+    "math.ratios" require
     "math.floats" require
     "memory" require
 
index 85f21badb4056857d0a74dd347e6af941469c0ec..96c63cb0fef7b91a192b2b3e958705a7eb1eb883 100644 (file)
@@ -235,6 +235,19 @@ HELP: sgn
     }
 } ;
 
+HELP: rect>
+{ $values { "x" real } { "y" real } { "z" number } }
+{ $description "Creates a complex number from real and imaginary components. If " { $snippet "z" } " is an integer zero, this will simply output " { $snippet "x" } "." } ;
+
+HELP: >rect
+{ $values { "z" number } { "x" real } { "y" real } }
+{ $description "Extracts the real and imaginary components of a complex number." } ;
+
+HELP: gcd
+{ $values { "x" integer } { "y" integer } { "a" integer } { "d" integer } }
+{ $description "Computes the positive greatest common divisor " { $snippet "d" } " of " { $snippet "x" } " and " { $snippet "y" } ", and another value " { $snippet "a" } " satisfying:" { $code "a*y = d mod x" } }
+{ $notes "If " { $snippet "d" } " is 1, then " { $snippet "a" } " is the inverse of " { $snippet "y" } " modulo " { $snippet "x" } "." } ;
+
 HELP: 2/
 { $values { "x" integer } { "y" integer } }
 { $description "Shifts " { $snippet "x" } " to the right by one bit." }
index ef7a8438d86f9540fe70f6b585b0e0bee2e3cd17..d7487502599c38258742c0dc4f06568943bd7f24 100644 (file)
@@ -98,3 +98,53 @@ IN: math.tests
 { t } [ 128 2^ neg sq 256 2^ = ] unit-test
 
 { t } [ most-negative-fixnum dup >bignum bignum>fixnum-strict = ] unit-test
+
+{ 100 } [ 100 100 gcd nip ] unit-test
+{ 100 } [ 1000 100 gcd nip ] unit-test
+{ 100 } [ 100 1000 gcd nip ] unit-test
+{ 4 } [ 132 64 gcd nip ] unit-test
+{ 4 } [ -132 64 gcd nip ] unit-test
+{ 4 } [ -132 -64 gcd nip ] unit-test
+{ 4 } [ 132 -64 gcd nip ] unit-test
+{ 4 } [ -132 -64 gcd nip ] unit-test
+
+{ 100 } [ 100 >bignum 100 >bignum gcd nip ] unit-test
+{ 100 } [ 1000 >bignum 100 >bignum gcd nip ] unit-test
+{ 100 } [ 100 >bignum 1000 >bignum gcd nip ] unit-test
+{ 4 } [ 132 >bignum 64 >bignum gcd nip ] unit-test
+{ 4 } [ -132 >bignum 64 >bignum gcd nip ] unit-test
+{ 4 } [ -132 >bignum -64 >bignum gcd nip ] unit-test
+{ 4 } [ 132 >bignum -64 >bignum gcd nip ] unit-test
+{ 4 } [ -132 >bignum -64 >bignum gcd nip ] unit-test
+
+{ 6 } [
+    1326264299060955293181542400000006
+    1591517158873146351817850880000000
+    gcd nip
+] unit-test
+
+{ 11 } [
+    13262642990609552931815424
+    159151715887314635181785
+    gcd nip
+] unit-test
+
+{ 3 } [
+    13262642990609552931
+    1591517158873146351
+    gcd nip
+] unit-test
+
+{ 26525285981219 } [
+    132626429906095
+    159151715887314
+    gcd nip
+] unit-test
+
+
+: verify-gcd ( a b -- ? )
+    2dup gcd
+    [ rot * swap rem ] dip = ;
+
+{ t } [ 123 124 verify-gcd ] unit-test
+{ t } [ 50 120 verify-gcd ] unit-test
index 5a0ba2fd4666b102b5be6d49565a79cfc592e190..ecf3e43001606fc82569469bf1893bc746f3faa4 100644 (file)
@@ -158,7 +158,9 @@ GENERIC: neg? ( x -- -x )
 
 UNION: integer fixnum bignum ;
 
-TUPLE: ratio { numerator integer read-only } { denominator integer read-only } ;
+TUPLE: ratio
+    { numerator integer read-only }
+    { denominator integer read-only } ;
 
 UNION: rational integer ratio ;
 
@@ -166,7 +168,9 @@ M: rational neg? 0 < ; inline
 
 UNION: real rational float ;
 
-TUPLE: complex { real real read-only } { imaginary real read-only } ;
+TUPLE: complex
+    { real real read-only }
+    { imaginary real read-only } ;
 
 UNION: number real complex ;
 
@@ -174,6 +178,42 @@ GENERIC: recip ( x -- y )
 
 M: number recip 1 swap / ; inline
 
+: rect> ( x y -- z )
+    ! Note: an imaginary 0.0 should still create a complex
+    dup 0 = [ drop ] [ complex boa ] if ; inline
+
+GENERIC: >rect ( z -- x y )
+
+M: real >rect 0 ; inline
+
+M: complex >rect [ real-part ] [ imaginary-part ] bi ; inline
+
+<PRIVATE
+
+: (gcd) ( b a x y -- a d )
+    swap [
+        nip
+    ] [
+        [ /mod [ over * swapd - ] dip ] keep (gcd)
+    ] if-zero ; inline recursive
+
+PRIVATE>
+
+: gcd ( x y -- a d )
+    [ 0 1 ] 2dip (gcd) dup 0 < [ neg ] when ; inline
+
+MATH: fast-gcd ( x y -- d ) foldable
+
+<PRIVATE
+
+: simple-gcd ( x y -- d ) gcd nip ; inline
+
+PRIVATE>
+
+M: real fast-gcd simple-gcd ; inline
+
+M: bignum fast-gcd bignum-gcd ; inline
+
 : fp-bitwise= ( x y -- ? ) [ double>bits ] same? ; inline
 
 GENERIC: fp-special? ( x -- ? )
diff --git a/core/math/ratios/authors.txt b/core/math/ratios/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/core/math/ratios/ratios-docs.factor b/core/math/ratios/ratios-docs.factor
new file mode 100644 (file)
index 0000000..57b37f1
--- /dev/null
@@ -0,0 +1,50 @@
+USING: help.markup help.syntax math math.private
+math.ratios.private math.functions ;
+IN: math.ratios
+
+ARTICLE: "rationals" "Rational numbers"
+{ $subsections ratio }
+"When we add, subtract or multiply any two integers, the result is always an integer. However, dividing a numerator by a denominator that is not an integral divisor of the denominator yields a ratio:"
+{ $example "1210 11 / ." "110" }
+{ $example "100 330 / ." "10/33" }
+{ $example "14 10 / ." "1+2/5" }
+"Ratios are printed and can be input literally in the form above. Ratios are always reduced to lowest terms by factoring out the greatest common divisor of the numerator and denominator. A ratio with a denominator of 1 becomes an integer. Division with a denominator of 0 throws an error."
+$nl
+"Ratios behave just like any other number -- all numerical operations work as you would expect."
+{ $example "1/2 1/3 + ." "5/6" }
+{ $example "100 6 / 3 * ." "50" }
+"Ratios can be taken apart:"
+{ $subsections
+    numerator
+    denominator
+    >fraction
+}
+{ $see-also "syntax-ratios" } ;
+
+ABOUT: "rationals"
+
+HELP: ratio
+{ $class-description "The class of rational numbers with denominator not equal to 1." } ;
+
+HELP: rational
+{ $class-description "The class of rational numbers, a disjoint union of integers and ratios." } ;
+
+HELP: numerator
+{ $values { "a/b" rational } { "a" integer } }
+{ $description "Outputs the numerator of a rational number. Acts as the identity on integers." } ;
+
+HELP: denominator
+{ $values { "a/b" rational } { "b" "a positive integer" } }
+{ $description "Outputs the denominator of a rational number. Always outputs 1 with integers." } ;
+
+HELP: fraction>
+{ $values { "a" integer } { "b" "a positive integer" } { "a/b" rational } }
+{ $description "Creates a new ratio, or outputs the numerator if the denominator is 1. This word does not reduce the fraction to lowest terms, and should not be called directly; use " { $link / } " instead." } ;
+
+HELP: >fraction
+{ $values { "a/b" rational } { "a" integer } { "b" "a positive integer" } }
+{ $description "Extracts the numerator and denominator of a rational number." } ;
+
+HELP: 2>fraction
+{ $values { "a/b" rational } { "c/d" rational } { "a" integer } { "c" integer } { "b" "a positive integer" } { "d" "a positive integer" } }
+{ $description "Extracts the numerator and denominator of two rational numbers at once." } ;
diff --git a/core/math/ratios/ratios-tests.factor b/core/math/ratios/ratios-tests.factor
new file mode 100644 (file)
index 0000000..0b44e95
--- /dev/null
@@ -0,0 +1,123 @@
+USING: kernel math math.order math.parser math.ratios
+math.functions tools.test ;
+IN: math.ratios.tests
+
+{ 1 2 } [ 1/2 >fraction ] unit-test
+
+{ 1/2 } [ 1 >bignum 2 >bignum / ] unit-test
+{ t } [ 10 3 / ratio? ] unit-test
+{ f } [ 10 2 / ratio? ] unit-test
+{ 10 } [ 10 numerator ] unit-test
+{ 1 } [ 10 denominator ] unit-test
+{ 12 } [ -12 -13 / numerator ] unit-test
+{ 13 } [ -12 -13 / denominator ] unit-test
+{ 1 } [ -1 -1 / numerator ] unit-test
+{ 1 } [ -1 -1 / denominator ] unit-test
+
+{ -1 } [ 2 -2 / ] unit-test
+{ -1 } [ -2 2 / ] unit-test
+
+{ t } [ 1 3 / 1 3 / = ] unit-test
+
+{ -10 } [ -100 10 /i ] unit-test
+{ 10 } [ -100 -10 /i ] unit-test
+{ -10 } [ 100 -10 /i ] unit-test
+{ -10 } [ -100 >bignum 10 >bignum /i ] unit-test
+{ 10  } [ -100 >bignum -10 >bignum /i ] unit-test
+{ -10 } [ 100 >bignum -10 >bignum /i ] unit-test
+
+{ 3/2 } [ 1 1/2 + ] unit-test
+{ 3/2 } [ 1 >bignum 1/2 + ] unit-test
+{ -1/2 } [ 1/2 1 - ] unit-test
+{ -1/2 } [ 1/2 1 >bignum - ] unit-test
+{ 41/20 } [ 5/4 4/5 + ] unit-test
+
+{ 1 } [ 1/2 2 * ] unit-test
+{ 1/3 } [ 1/2 2/3 * ] unit-test
+
+{ 1 } [ 1/2 1/2 / ] unit-test
+{ 27/4 } [ 3/2 2/9 / ] unit-test
+
+{ t } [ 5768 476343 < ] unit-test
+{ t } [ 5768 476343 <= ] unit-test
+{ f } [ 5768 476343 > ] unit-test
+{ f } [ 5768 476343 >= ] unit-test
+{ t } [ 3434 >bignum 3434 >= ] unit-test
+{ t } [ 3434 3434 >bignum <= ] unit-test
+
+{ t } [ 1 1/3 > ] unit-test
+{ t } [ 2/3 3/4 <= ] unit-test
+{ f } [ -2/3 1/3 > ] unit-test
+
+{ t } [ 1000000000/999999 1000 > ] unit-test
+{ f } [ 100000 100000000000/999999 > ] unit-test
+{ t }
+[ 1000000000000/999999999999 1000000000001/999999999998 < ]
+unit-test
+
+{ -3 } [ -3 10 mod ] unit-test
+{ 7 } [ -3 10 rem ] unit-test
+{ 7 } [ -13 10 rem ] unit-test
+{ 0 } [ 37 37 rem ] unit-test
+
+{ -1 } [ -12.55 sgn ] unit-test
+{ 1 } [ 100000000000000000000000000000000 sgn ] unit-test
+{ 0 } [ 0.0 sgn ] unit-test
+
+{ 1/2 } [ 1/2 1 mod ] unit-test
+{ 1/3 } [ 10/3 3 mod ] unit-test
+{ -1/3 } [ -10/3 3 mod ] unit-test
+
+{ 4 1/2 } [ 3+1/2 3/4 /mod ] unit-test
+{ -4 -1/2 } [ -3-1/2 3/4 /mod ] unit-test
+{ 4 -1/2 } [ -3-1/2 -3/4 /mod ] unit-test
+{ -4 1/2 } [ 3+1/2 -3/4 /mod ] unit-test
+
+{ 5 } [ 5 floor ] unit-test
+{ -5 } [ -5 floor ] unit-test
+{ 6 } [ 6 truncate ] unit-test
+{ 3 } [ 10/3 floor ] unit-test
+{ -4 } [ -10/3 floor ] unit-test
+{ 4 } [ 10/3 ceiling ] unit-test
+{ -3 } [ -10/3 ceiling ] unit-test
+{ 3 } [ 10/3 truncate ] unit-test
+{ -3 } [ -10/3 truncate ] unit-test
+
+{ -1/2 } [ 1/2 1 - ] unit-test
+{ 3/2 } [ 1/2 1 + ] unit-test
+
+{ 1.0 } [ 0.5 1/2 + ] unit-test
+{ 1.0 } [ 1/2 0.5 + ] unit-test
+
+{ 1/134217728 } [ -1 -134217728 >fixnum / ] unit-test
+{ 134217728 } [ -134217728 >fixnum -1 / ] unit-test
+
+{ 5 }
+[ "10/2" string>number ]
+unit-test
+
+{ -5 }
+[ "-10/2" string>number ]
+unit-test
+
+{ f }
+[ "10/-2" string>number ]
+unit-test
+
+{ f }
+[ "-10/-2" string>number ]
+unit-test
+
+{ "33/100" }
+[ "66/200" string>number number>string ]
+unit-test
+
+{ 3 } [ "1+1/2" string>number 2 * ] unit-test
+{ -3 } [ "-1-1/2" string>number 2 * ] unit-test
+{ "2+1/7" } [ 1 7 / 2 + number>string ] unit-test
+{ "1/8" } [ 1 8 / number>string ] unit-test
+
+{ t } [ 2/3 dup number= ] unit-test
+{ t } [ 2/33333333333333333333333333333333 dup number= ] unit-test
+{ t } [ -2/3 dup number= ] unit-test
+{ t } [ -2/33333333333333333333333333333333 dup number= ] unit-test
diff --git a/core/math/ratios/ratios.factor b/core/math/ratios/ratios.factor
new file mode 100644 (file)
index 0000000..167d335
--- /dev/null
@@ -0,0 +1,78 @@
+! Copyright (C) 2004, 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel math ;
+IN: math.ratios
+
+: 2>fraction ( a/b c/d -- a c b d )
+    [ >fraction ] bi@ swapd ; inline
+
+<PRIVATE
+
+: fraction> ( a b -- a/b )
+    dup 1 number= [ drop ] [ ratio boa ] if ; inline
+
+: (scale) ( a b c d -- a*d b*c )
+    [ * swap ] dip * swap ; inline
+
+: scale ( a/b c/d -- a*d b*c )
+    2>fraction (scale) ; inline
+
+: scale+d ( a/b c/d -- a*d b*c b*d )
+    2>fraction [ (scale) ] 2keep * ; inline
+
+PRIVATE>
+
+ERROR: division-by-zero x ;
+
+M: integer /
+    [
+        division-by-zero
+    ] [
+        dup 0 < [ [ neg ] bi@ ] when
+        2dup fast-gcd [ /i ] curry bi@ fraction>
+    ] if-zero ;
+
+M: integer recip
+    1 swap [
+        division-by-zero
+    ] [
+        dup 0 < [ [ neg ] bi@ ] when fraction>
+    ] if-zero ;
+
+M: ratio recip
+    >fraction swap dup 0 < [ [ neg ] bi@ ] when fraction> ;
+
+M: ratio hashcode*
+    nip >fraction [ hashcode ] bi@ bitxor ;
+
+M: ratio equal?
+    over ratio? [
+        2>fraction = [ = ] [ 2drop f ] if
+    ] [ 2drop f ] if ;
+
+M: ratio number=
+    2>fraction number= [ number= ] [ 2drop f ] if ;
+
+M: ratio >fixnum >fraction /i >fixnum ;
+M: ratio >bignum >fraction /i >bignum ;
+M: ratio >float >fraction /f ;
+
+M: ratio numerator numerator>> ; inline
+M: ratio denominator denominator>> ; inline
+M: ratio >fraction [ numerator ] [ denominator ] bi ; inline
+
+M: ratio < scale < ;
+M: ratio <= scale <= ;
+M: ratio > scale > ;
+M: ratio >= scale >= ;
+
+M: ratio + scale+d [ + ] [ / ] bi* ;
+M: ratio - scale+d [ - ] [ / ] bi* ;
+M: ratio * 2>fraction [ * ] 2bi@ / ;
+M: ratio / scale / ;
+M: ratio /i scale /i ;
+M: ratio /f scale /f ;
+M: ratio mod scale+d [ mod ] [ / ] bi* ;
+M: ratio /mod scale+d [ /mod ] [ / ] bi* ;
+M: ratio abs dup neg? [ >fraction [ neg ] dip fraction> ] when ;
+M: ratio neg? numerator neg? ; inline
diff --git a/core/math/ratios/summary.txt b/core/math/ratios/summary.txt
new file mode 100644 (file)
index 0000000..6077e3d
--- /dev/null
@@ -0,0 +1 @@
+Rational number implementation