aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2023-11-06 00:40:42 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2023-11-16 00:51:19 +0100
commit29a5d5824ca874b2635f9e812e25198e42b5efc1 (patch)
tree568510802535956085a5ea99c3498780be9dae8d
parentFix swedish ordinals. (diff)
downloadcalp-29a5d5824ca874b2635f9e812e25198e42b5efc1.tar.gz
calp-29a5d5824ca874b2635f9e812e25198e42b5efc1.tar.xz
Add procedures for printing big numbers.
-rw-r--r--module/text/big-numbers.scm31
-rw-r--r--tests/unit/text/big-numbers.scm22
2 files changed, 53 insertions, 0 deletions
diff --git a/module/text/big-numbers.scm b/module/text/big-numbers.scm
new file mode 100644
index 00000000..325cc2f3
--- /dev/null
+++ b/module/text/big-numbers.scm
@@ -0,0 +1,31 @@
+(define-module (text big-numbers)
+ :use-module ((hnh util) :select (->>))
+ :use-module (hnh util type)
+ :export (number->exponential-form
+ power-of-10?
+ subscript supscript))
+
+(define (integer-string-ref str n)
+ (typecheck str string?)
+ (typecheck n (and exact? integer?))
+ (->> n
+ number->string
+ string->list
+ (map char->integer)
+ (map (lambda (x) (- x (char->integer #\0))))
+ (map (lambda (i) (string-ref str i)))
+ list->string))
+
+(define (subscript n)
+ (integer-string-ref "₀₁₂₃₄₅₆₇₈₉" n))
+
+(define (supscript n)
+ (integer-string-ref "⁰¹²³⁴⁵⁶⁷⁸⁹" n))
+
+;;; Is the number a power of 10?
+(define (power-of-10? x)
+ (integer? (log10 (exact->inexact x))))
+
+(define (number->exponential-form n)
+ (typecheck n (and exact? integer? power-of-10?))
+ (string-append "10" (supscript (inexact->exact (round (log10 n))))))
diff --git a/tests/unit/text/big-numbers.scm b/tests/unit/text/big-numbers.scm
new file mode 100644
index 00000000..2fb2a736
--- /dev/null
+++ b/tests/unit/text/big-numbers.scm
@@ -0,0 +1,22 @@
+(define-module (test text-big-numbers)
+ :use-module (srfi srfi-64)
+ :use-module (srfi srfi-64 test-error)
+ :use-module (text big-numbers))
+
+(test-assert (power-of-10? #e1e100))
+(test-assert (power-of-10? 1e100))
+;; (test-assert (not (power-of-10? (+ #e1e100 1))))
+;; (test-assert (not (power-of-10? (+ 1e100 1))))
+;; (test-assert (not (power-of-10? (- #e1e100 1))))
+;; (test-assert (not (power-of-10? (- 1e100 1))))
+
+(test-equal "₉₆₈₀₂₃₇₄₅₁" (subscript 9680237451))
+(test-equal "⁹⁶⁸⁰²³⁷⁴⁵¹" (supscript 9680237451))
+
+(test-equal "10¹⁰⁰"
+ (number->exponential-form #e1e100))
+
+(test-error 'wrong-type-arg
+ (number->exponential-form 20))
+
+'((text big-numbers))