I would like to write a function NumberParts that takes an integer or real and returns it as a list with the list of digits composing the number in a list along with the exponent i.e. the number of places that one must move the decimal point left or right. Some examples:
123 -> ((1 2 3) 3)
-12 -> ((-1 -2) 2)
0.12 -> ((1 2) 0)
0.00045 -> ((4 5) -3)
One notes that negative numbers have negative digits in the digit list. My question is what is the best way to do this to get the full precision of both integers and reals? It is trivial to convert such a list into a number but I am not certain of the best way to do the reverse. Any suggestions?
Splitting Numbers into component parts
-
- Posts: 95
- Joined: Wed Oct 13, 2004 8:02 pm
- Location: Bellingham WA
Here's a lame way to do it:
Usage and output:
So you can see that I recommend you put your sign somewhere in the list (I have it in position 1), rather than signing every component in the digit list. Also notice that '0' and '-0' are handled in a way that corresponds to how the newLISP REPL does.
Someone better at this will give you a better answer. Maybe the lame code given by me will spur them on to give you something better. :-)
--Rick
Code: Select all
(define (re-remove re str) (replace re str "" 0))
(define (split-number-at-point n)
(let ((n-split (parse (format "%f" (float n)) "."))
(sign (if (< n 0) -1 1)))
(list sign
(re-remove "^0+" (re-remove "^-" (n-split 0)))
(re-remove "0+$" (n-split 1)))))
(define (extract-digits str) (map int (explode str)))
(define (number->parts n)
(letn ((s (split-number-at-point n))
(sign (s 0))
(r_0 (extract-digits (s 1)))
(l_0 (s 2))
(l (extract-digits (if (empty? r_0)
(re-remove "^0+" l_0)
l_0)))
(r (if (and (empty? l_0) (empty? r_0)) '(0) r_0)))
(list sign
(append r l)
(+ (length r)
(- (length l) (length l_0))))))
Code: Select all
> (number->parts 0.00045)
(1 (4 5) -3)
> (number->parts -0.00045)
(-1 (4 5) -3)
> (number->parts 42.00045)
(1 (4 2 0 0 0 4 5) 2)
> (number->parts 123)
(1 (1 2 3) 3)
> (number->parts -12)
(-1 (1 2) 2)
> (number->parts 0.12)
(1 (1 2) 0)
> (number->parts -0.12)
(-1 (1 2) 0)
> (number->parts 0)
(1 (0) 1)
> (number->parts -0)
(1 (0) 1)
> 0
0
> -0
0
Someone better at this will give you a better answer. Maybe the lame code given by me will spur them on to give you something better. :-)
--Rick
(λx. x x) (λx. x x)