1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel math.private namespaces sequences strings
4 arrays combinators splitting math assocs make ;
33 : string>digits ( str -- digits )
34 [ digit> ] { } map-as ;
36 : digits>integer ( seq radix -- n )
37 0 swap [ swapd * + ] curry reduce ;
46 : sign ( -- str ) negative? get "-" "+" ? ;
48 : with-radix ( radix quot -- )
49 radix swap with-variable ; inline
51 : (base>) ( str -- n ) radix get base> ;
53 : whole-part ( str -- m n )
54 sign split1 [ (base>) ] dip
55 dup [ (base>) ] [ drop 0 swap ] if ;
57 : string>ratio ( str -- a/b )
58 "-" ?head dup negative? set swap
59 "/" split1 (base>) [ whole-part ] dip
60 3dup and and [ / + swap [ neg ] when ] [ 2drop 2drop f ] if ;
62 : valid-digits? ( seq -- ? )
64 { [ dup empty? ] [ drop f ] }
65 { [ f over memq? ] [ drop f ] }
66 [ radix get [ < ] curry all? ]
69 : string>integer ( str -- n/f )
71 string>digits dup valid-digits?
72 [ radix get digits>integer swap [ neg ] when ] [ 2drop f ] if ;
76 : base> ( str radix -- n/f )
78 CHAR: / over member? [
81 CHAR: . over member? [
89 : string>number ( str -- n/f ) 10 base> ;
90 : bin> ( str -- n/f ) 2 base> ;
91 : oct> ( str -- n/f ) 8 base> ;
92 : hex> ( str -- n/f ) 16 base> ;
95 dup 10 < [ CHAR: 0 + ] [ 10 - CHAR: a + ] if ;
97 : positive>base ( num radix -- str )
98 dup 1 <= [ "Invalid radix" throw ] when
99 [ dup 0 > ] swap [ /mod >digit ] curry [ ] "" produce-as nip
100 dup reverse-here ; inline
104 GENERIC# >base 1 ( n radix -- str )
108 : (>base) ( n -- str ) radix get positive>base ;
119 [ neg ] dip positive>base CHAR: - prefix
125 dup 0 < negative? set
127 [ dup zero? [ drop "" ] [ (>base) sign append ] if ]
129 [ numerator (>base) ]
130 [ denominator (>base) ] bi
133 negative? get [ CHAR: - prefix ] when
136 : fix-float ( str -- newstr )
139 [ CHAR: e over member? ]
140 [ "e" split1 [ fix-float "e" ] dip 3append ]
142 [ CHAR: . over member? ]
150 { [ dup fp-nan? ] [ drop "0.0/0.0" ] }
151 { [ dup 1.0/0.0 = ] [ drop "1.0/0.0" ] }
152 { [ dup -1.0/0.0 = ] [ drop "-1.0/0.0" ] }
153 { [ dup double>bits HEX: 8000000000000000 = ] [ drop "-0.0" ] }
154 [ float>string fix-float ]
157 : number>string ( n -- str ) 10 >base ;
158 : >bin ( n -- str ) 2 >base ;
159 : >oct ( n -- str ) 8 >base ;
160 : >hex ( n -- str ) 16 >base ;
162 : # ( n -- ) number>string % ;