integertostring.scm 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ;Date: Mon, 24 Jan 94 15:10:30 -0500
  4. ;To: jar@ai.mit.edu
  5. ;Subject: integer->string
  6. ;From: kelsey@research.nj.nec.com
  7. ;Sender: kelsey@research.nj.nec.com
  8. ;
  9. ;
  10. ;I have gotten tired of waiting for bignums to print out.
  11. ;Here is a somewhat more complex and faster version of integer->string.
  12. ;
  13. ;Converting 10**100 to a string:
  14. ; Current: 0.44 seconds
  15. ; This: 0.12 seconds
  16. ; This using integer-divide: 0.06 seconds
  17. ;
  18. ;There is no overwhelming reason to use this, but here it is.
  19. (define integer->string
  20. (let ()
  21. (define (integer->string n radix)
  22. (define (small-integer->magnitude n l)
  23. (if (= n 0)
  24. l
  25. (small-integer->magnitude (quotient n radix)
  26. (cons (integer->digit (remainder n radix))
  27. l))))
  28. (define (integer->magnitude n)
  29. (let ((rrrr (* (* radix radix) (* radix radix))))
  30. (let recur ((n n) (l '()))
  31. (if (< n rrrr)
  32. (small-integer->magnitude n l)
  33. (do ((i 4 (- i 1))
  34. (n0 (remainder n rrrr) (quotient n0 radix))
  35. (l l (cons (integer->digit (remainder n0 radix)) l)))
  36. ((= 0 i)
  37. (recur (quotient n rrrr) l)))))))
  38. (let ((magnitude (cond ((= n 0) '(#\0))
  39. ((< n 1000000)
  40. (small-integer->magnitude (abs n) '()))
  41. (else
  42. (integer->magnitude (abs n))))))
  43. (list->string (if (>= n 0)
  44. magnitude
  45. (cons #\- magnitude)))))
  46. (define (integer->digit n)
  47. (ascii->char (+ n (if (< n 10)
  48. zero
  49. a-minus-10))))
  50. (define zero (char->ascii #\0))
  51. (define a-minus-10 (- (char->ascii #\a) 10))
  52. integer->string))