1 ! Copyright (C) 2004, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel math.private namespaces sequences sequences.private
4 strings arrays combinators splitting math assocs byte-arrays make ;
32 } at* [ drop 255 ] unless ; inline
34 : string>digits ( str -- digits )
35 [ digit> ] B{ } map-as ; inline
37 : (digits>integer) ( valid? accum digit radix -- valid? accum )
39 2dup < [ swapd * + ] [ 2drop 2drop f 0 ] if
40 ] [ 2drop ] if ; inline
42 : each-digit ( seq radix quot -- n/f )
43 [ t 0 ] 3dip curry each swap [ drop f ] unless ; inline
45 : digits>integer ( seq radix -- n/f )
46 [ (digits>integer) ] each-digit ; inline
55 : string>natural ( seq radix -- n/f )
56 over empty? [ 2drop f ] [
57 [ [ digit> ] dip (digits>integer) ] each-digit
60 : sign ( -- str ) negative? get "-" "+" ? ;
62 : with-radix ( radix quot -- )
63 radix swap with-variable ; inline
65 : (base>) ( str -- n ) radix get base> ;
67 : whole-part ( str -- m n )
68 sign split1 [ (base>) ] dip
69 dup [ (base>) ] [ drop 0 swap ] if ;
71 : string>ratio ( str radix -- a/b )
73 "-" ?head dup negative? set swap
74 "/" split1 (base>) [ whole-part ] dip
75 3dup and and [ / + swap [ neg ] when ] [ 2drop 2drop f ] if
78 : string>integer ( str radix -- n/f )
79 over first-unsafe CHAR: - = [
80 [ rest-slice ] dip string>natural dup [ neg ] when
85 : string>float ( str -- n/f )
86 [ CHAR: , eq? not ] filter
87 >byte-array 0 suffix (string>float) ;
91 : base> ( str radix -- n/f )
92 over empty? [ 2drop f ] [
93 over [ "/." member? ] find nip {
94 { CHAR: / [ string>ratio ] }
95 { CHAR: . [ drop string>float ] }
96 [ drop string>integer ]
100 : string>number ( str -- n/f ) 10 base> ;
101 : bin> ( str -- n/f ) 2 base> ;
102 : oct> ( str -- n/f ) 8 base> ;
103 : hex> ( str -- n/f ) 16 base> ;
106 dup 10 < [ CHAR: 0 + ] [ 10 - CHAR: a + ] if ;
108 : positive>base ( num radix -- str )
109 dup 1 <= [ "Invalid radix" throw ] when
110 [ dup 0 > ] swap [ /mod >digit ] curry "" produce-as nip
111 dup reverse-here ; inline
115 GENERIC# >base 1 ( n radix -- str )
119 : (>base) ( n -- str ) radix get positive>base ;
130 [ neg ] dip positive>base CHAR: - prefix
136 dup 0 < negative? set
138 [ [ "" ] [ (>base) sign append ] if-zero ]
140 [ numerator (>base) ]
141 [ denominator (>base) ] bi
144 negative? get [ CHAR: - prefix ] when
147 : fix-float ( str -- newstr )
150 [ CHAR: e over member? ]
151 [ "e" split1 [ fix-float "e" ] dip 3append ]
153 [ CHAR: . over member? ]
159 : float>string ( n -- str )
161 [ 0 = ] trim-tail >string
166 { [ dup fp-nan? ] [ drop "0/0." ] }
167 { [ dup 1/0. = ] [ drop "1/0." ] }
168 { [ dup -1/0. = ] [ drop "-1/0." ] }
169 { [ dup double>bits HEX: 8000000000000000 = ] [ drop "-0.0" ] }
173 : number>string ( n -- str ) 10 >base ;
174 : >bin ( n -- str ) 2 >base ;
175 : >oct ( n -- str ) 8 >base ;
176 : >hex ( n -- str ) 16 >base ;
178 : # ( n -- ) number>string % ;