## Big Numbers: Input And Output

### June 14, 2011

These functions are straight forward, and assume that the radix is less than or equal to `big-base`:

```(define (string->big str . args)   (define (char->digit c)     (cond ((char-numeric? c) (- (char->integer c) 48))           ((char-upper-case? c) (- (char->integer c) 55))           ((char-lower-case? c) (- (char->integer c) 87))           (else (error 'char->digit "illegal character"))))   (if (string=? str "") '(0)     (let* ((radix (list 1 (if (null? args) 10 (car args))))            (s (if (char=? (string-ref str 0) #\-) -1 1))            (ds (string->list str))            (ds (if (positive? s) ds (cdr ds)))            (ds (map char->digit ds)))       (let loop ((ds (cdr ds)) (big (list 1 (car ds))))         (if (null? ds) (cons (* s (car big)) (cdr big))           (loop (cdr ds)                 (big-plus (big-times big radix)                           (list 1 (car ds)))))))))```

```(define (big->string big . args)   (define (digit->char d)     (cond ((< d 10) (integer->char (+ d 48)))           ((< d 36) (integer->char (+ d 55)))           (else (error 'digit->char "illegal digit"))))   (if (big-zero? big) "0"     (if (big-negative? big) (string-append "-" (big->string (big-negate big)))       (let ((radix (list 1 (if (null? args) 10 (car args)))))         (let loop ((big big) (ds '()))           (if (big-zero? big) (list->string ds)             (call-with-values               (lambda () (big-divide big radix))               (lambda (q r) (loop q (cons (digit->char (cadr r)) ds))))))))))```

Testing these functions turned up a big in `big-divide`: when the quotient was zero, it was represented as `(1 0)` instead of the correct representation `(0)`.

The complete big-number library to this point is shown on the next page. You can run the program at http://programmingpraxis.codepad.org/4TvtUDo3.

Pages: 1 2 3

### One Response to “Big Numbers: Input And Output”

1. My Haskell solution (see http://bonsaicode.wordpress.com/2011/06/14/programming-praxis-big-numbers-input-and-output/ for a version with comments):

```readBase :: (Num a, Enum a) => a -> String -> a
readBase b ('-':xs) = - readBase b xs
readBase b xs       = foldl (\a x -> b * a + val x) 0 xs where
val d = maybe (error "unrecognized digit") id . lookup d \$ zip
(['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z']) [0..]

showBase :: Integral a => a -> a -> String
showBase b n = if n < 0 then '-' : showBase b (abs n) else
map (digit . snd) \$ m : reverse ms  where
((_:ms), (m:_)) = span ((> 0) . fst) \$ iterate (flip divMod b . fst) (n, 0)
digit d = maybe undefined id . lookup d . zip [0..] \$
['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z']
```