1 ! Copyright (C) 2003, 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel math.private ;
6 GENERIC: >fixnum ( x -- y ) foldable
7 GENERIC: >bignum ( x -- y ) foldable
8 GENERIC: >float ( x -- y ) foldable
10 MATH: number= ( x y -- ? ) foldable
11 M: object number= 2drop f ;
13 MATH: < ( x y -- ? ) foldable
14 MATH: <= ( x y -- ? ) foldable
15 MATH: > ( x y -- ? ) foldable
16 MATH: >= ( x y -- ? ) foldable
18 MATH: + ( x y -- z ) foldable
19 MATH: - ( x y -- z ) foldable
20 MATH: * ( x y -- z ) foldable
21 MATH: / ( x y -- z ) foldable
22 MATH: /i ( x y -- z ) foldable
23 MATH: mod ( x y -- z ) foldable
25 MATH: /mod ( x y -- z w ) foldable
27 MATH: bitand ( x y -- z ) foldable
28 MATH: bitor ( x y -- z ) foldable
29 MATH: bitxor ( x y -- z ) foldable
30 GENERIC# shift 1 ( x n -- y ) foldable
31 GENERIC: bitnot ( x -- y ) foldable
32 GENERIC# bit? 1 ( x n -- ? ) foldable
36 GENERIC: (log2) ( x -- n ) foldable
42 "log2 expects positive inputs" throw
47 GENERIC: zero? ( x -- ? ) foldable
49 M: object zero? drop f ;
51 GENERIC: sqrt ( x -- y ) foldable
53 : 1+ ( x -- y ) 1 + ; foldable
54 : 1- ( x -- y ) 1 - ; foldable
55 : 2/ ( x -- y ) -1 shift ; foldable
56 : sq ( x -- y ) dup * ; foldable
57 : neg ( x -- -x ) 0 swap - ; foldable
58 : recip ( x -- y ) 1 swap / ; foldable
60 : /f ( x y -- z ) >r >float r> >float float/f ; inline
62 : max ( x y -- z ) [ > ] most ; foldable
63 : min ( x y -- z ) [ < ] most ; foldable
65 : between? ( x y z -- ? )
66 pick >= [ >= ] [ 2drop f ] if ; inline
68 : rem ( x y -- z ) tuck mod over + swap mod ; foldable
69 : sgn ( x -- n ) dup 0 < -1 0 ? swap 0 > 1 0 ? bitor ; foldable
70 : truncate ( x -- y ) dup 1 mod - ; inline
71 : round ( x -- y ) dup sgn 2 / + truncate ; inline
75 [ drop ] [ dup 0 < [ - 1- ] [ - ] if ] if ; foldable
77 : ceiling ( x -- y ) neg floor neg ; foldable
79 : [-] ( x y -- z ) - 0 max ; inline
81 : 2^ ( n -- 2^n ) 1 swap shift ; inline
83 : even? ( n -- ? ) 1 bitand zero? ;
85 : odd? ( n -- ? ) 1 bitand 1 number= ;
87 : >fraction ( a/b -- a b )
88 dup numerator swap denominator ; inline
90 UNION: integer fixnum bignum ;
92 UNION: rational integer ratio ;
94 UNION: real rational float ;
96 UNION: number real complex ;
98 GENERIC: fp-nan? ( x -- ? )
104 double>bits -51 shift BIN: 111111111111 [ bitand ] keep
109 : (rect>) ( x y -- z )
110 dup zero? [ drop ] [ <complex> ] if ; inline
115 over real? over real? and [
118 "Complex number must have real components" throw
121 : >rect ( z -- x y ) dup real swap imaginary ; inline
123 : >float-rect ( z -- x y )
124 >rect swap >float swap >float ; inline
126 : (next-power-of-2) ( i n -- n )
130 >r 1 shift r> (next-power-of-2)
133 : next-power-of-2 ( m -- n ) 2 swap (next-power-of-2) ; foldable
137 : iterate-prep 0 -rot ; inline
139 : if-iterate? >r >r pick pick < r> r> if ; inline
141 : iterate-step ( i n quot -- i n quot )
142 #! Apply quot to i, keep i and quot, hide n.
143 swap >r 2dup 2slip r> swap ; inline
145 : iterate-next >r >r 1+ r> r> ; inline
149 : (each-integer) ( i n quot -- )
150 [ iterate-step iterate-next (each-integer) ]
151 [ 3drop ] if-iterate? ; inline
153 : (find-integer) ( i n quot -- i )
156 [ 2drop ] [ iterate-next (find-integer) ] if
157 ] [ 3drop f ] if-iterate? ; inline
159 : (all-integers?) ( i n quot -- ? )
162 [ iterate-next (all-integers?) ] [ 3drop f ] if
163 ] [ 3drop t ] if-iterate? ; inline
165 : each-integer ( n quot -- )
166 iterate-prep (each-integer) ; inline
168 : times ( n quot -- )
169 [ drop ] swap compose each-integer ; inline
171 : find-integer ( n quot -- i )
172 iterate-prep (find-integer) ; inline
174 : all-integers? ( n quot -- ? )
175 iterate-prep (all-integers?) ; inline
177 : find-last-integer ( n quot -- i )
184 >r 1- r> find-last-integer