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 ;
33 : string>digits ( str -- digits )
34 [ digit> ] B{ } map-as ; inline
36 : (digits>integer) ( valid? accum digit radix -- valid? accum )
37 2dup < [ swapd * + ] [ 2drop 2drop f 0 ] if ; inline
39 : each-digit ( seq radix quot -- n/f )
40 [ t 0 ] 3dip curry each swap [ drop f ] unless ; inline
42 : digits>integer ( seq radix -- n/f )
43 [ (digits>integer) ] each-digit ; inline
52 : string>natural ( seq radix -- n/f )
53 over empty? [ 2drop f ] [
54 [ [ digit> ] dip (digits>integer) ] each-digit
57 : sign ( -- str ) negative? get "-" "+" ? ;
59 : with-radix ( radix quot -- )
60 radix swap with-variable ; inline
62 : (base>) ( str -- n ) radix get base> ;
64 : whole-part ( str -- m n )
65 sign split1 [ (base>) ] dip
66 dup [ (base>) ] [ drop 0 swap ] if ;
68 : string>ratio ( str radix -- a/b )
70 "-" ?head dup negative? set swap
71 "/" split1 (base>) [ whole-part ] dip
72 3dup and and [ / + swap [ neg ] when ] [ 2drop 2drop f ] if
75 : string>integer ( str radix -- n/f )
76 over first-unsafe CHAR: - = [
77 [ rest-slice ] dip string>natural dup [ neg ] when
82 : string>float ( str -- n/f )
83 >byte-array 0 suffix (string>float) ;
87 : base> ( str radix -- n/f )
88 over empty? [ 2drop f ] [
89 over [ "/." member? ] find nip {
90 { CHAR: / [ string>ratio ] }
91 { CHAR: . [ drop string>float ] }
92 [ drop string>integer ]
96 : string>number ( str -- n/f ) 10 base> ;
97 : bin> ( str -- n/f ) 2 base> ;
98 : oct> ( str -- n/f ) 8 base> ;
99 : hex> ( str -- n/f ) 16 base> ;
102 dup 10 < [ CHAR: 0 + ] [ 10 - CHAR: a + ] if ;
104 : positive>base ( num radix -- str )
105 dup 1 <= [ "Invalid radix" throw ] when
106 [ dup 0 > ] swap [ /mod >digit ] curry "" produce-as nip
107 dup reverse-here ; inline
111 GENERIC# >base 1 ( n radix -- str )
115 : (>base) ( n -- str ) radix get positive>base ;
126 [ neg ] dip positive>base CHAR: - prefix
132 dup 0 < negative? set
134 [ dup zero? [ drop "" ] [ (>base) sign append ] if ]
136 [ numerator (>base) ]
137 [ denominator (>base) ] bi
140 negative? get [ CHAR: - prefix ] when
143 : fix-float ( str -- newstr )
146 [ CHAR: e over member? ]
147 [ "e" split1 [ fix-float "e" ] dip 3append ]
149 [ CHAR: . over member? ]
155 : float>string ( n -- str )
157 [ 0 = ] trim-tail >string
162 { [ dup fp-nan? ] [ drop "0/0." ] }
163 { [ dup 1/0. = ] [ drop "1/0." ] }
164 { [ dup -1/0. = ] [ drop "-1/0." ] }
165 { [ dup double>bits HEX: 8000000000000000 = ] [ drop "-0.0" ] }
169 : number>string ( n -- str ) 10 >base ;
170 : >bin ( n -- str ) 2 >base ;
171 : >oct ( n -- str ) 8 >base ;
172 : >hex ( n -- str ) 16 >base ;
174 : # ( n -- ) number>string % ;