Skip to content

Instantly share code, notes, and snippets.

@brv00
Created November 21, 2019 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brv00/c15c31fe1c1b1337925cf586b4e2f888 to your computer and use it in GitHub Desktop.
Save brv00/c15c31fe1c1b1337925cf586b4e2f888 to your computer and use it in GitHub Desktop.
(define max-ndigits 8)
(define (i/% x y)
(let ((q (/ x y)) (r (% x y))) (if (< r 0) (list (-- q) (+ r y)) (list q r))))
(define (get-padding xs n) (build-list (max 0 (- n (length xs))) (lambda (_) 0)))
(define (trim xs n) (take (append xs (get-padding xs n)) n))
(define (drop0s xs) (if (and (cons? xs) (= (car xs) 0)) (drop0s (cdr xs)) xs))
(define-struct num (sign i f)) (define plus "") (define minus "-")
(define (mul-signs-of x y) (if (string=? (num-sign x) (num-sign y)) plus minus))
(define (num->list x) (append (num-i x) (num-f x)))
(define (num->int x) (foldl (lambda (n i) (+ n (* 10 i))) 0 (num->list x)))
(define (ldiv xs y carry-digit)
(foldl (lambda (x ds) (append (reverse (i/% (+ x (* 10 (car ds))) y)) (cdr ds)))
(list carry-digit) xs))
(define (div x y)
(let ((sign (mul-signs-of x y)) (lfy (length (num-f y))) (y (num->int y)))
(let* ((ix (append (num-i x) (trim (num-f x) lfy))) (rq (ldiv ix y 0))
(i (drop0s (reverse (cdr rq)))) (i (if (null? i) '(0) i)))
(if (> (length i) max-ndigits)
(make-num sign i '())
(let ((fx (drop (trim (num-f x) (- (+ max-ndigits lfy) (length i))) lfy)))
(make-num sign i (reverse (drop0s (cdr (ldiv fx y (car rq)))))))))))
"3330088÷106"
(div (make-num plus '(3 3 3 0 0 8 8) '()) (make-num plus '(1 0 6) '()))
"1÷11"
(div (make-num plus '(1) '()) (make-num plus '(1 1) '()))
"99999999÷0.5"
(div (make-num plus '(9 9 9 9 9 9 9 9) '()) (make-num plus '(0) '(5)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment