(deftest "math completeness" (deftest "trigonometry" (deftest "sin" (assert= 0 (round (sin 0)) "sin 0 = 0") (assert= 1 (round (sin (/ 3.14159 2))) "sin pi/2 = 1") (assert= 0 (round (sin 3.14159)) "sin pi = 0")) (deftest "cos" (assert= 1 (round (cos 0)) "cos 0 = 1") (assert= 0 (round (cos (/ 3.14159 2))) "cos pi/2 = 0") (assert= -1 (round (cos 3.14159)) "cos pi = -1")) (deftest "tan" (assert= 0 (round (tan 0)) "tan 0 = 0") (assert= 1 (round (tan 0.785398)) "tan pi/4 = 1")) (deftest "asin" (assert= 0 (round (asin 0)) "asin 0 = 0") (let (r (asin 1)) (assert= true (and (> r 1.5) (< r 1.6)) "asin 1 ≈ pi/2"))) (deftest "acos" (assert= 0 (round (acos 1)) "acos 1 = 0") (let (r (acos 0)) (assert= true (and (> r 1.5) (< r 1.6)) "acos 0 ≈ pi/2"))) (deftest "atan" (assert= 0 (round (atan 0)) "atan 0 = 0") (let (r (atan 1)) (assert= true (and (> r 0.78) (< r 0.8)) "atan 1 ≈ pi/4")) (let (r (atan 1 1)) (assert= true (and (> r 0.78) (< r 0.8)) "atan 1 1 = atan2(1,1) ≈ pi/4")) (let (r (atan 1 0)) (assert= true (and (> r 1.5) (< r 1.6)) "atan 1 0 ≈ pi/2"))) (deftest "exp" (assert= 1 (round (exp 0)) "exp 0 = 1") (let (r (exp 1)) (assert= true (and (> r 2.71) (< r 2.72)) "exp 1 ≈ e"))) (deftest "log" (assert= 0 (round (log 1)) "log 1 = 0") (let (r (log 2.71828)) (assert= true (and (> r 0.99) (< r 1.01)) "log e ≈ 1")))) (deftest "expt" (assert= 8 (expt 2 3) "2^3 = 8") (assert= 1 (expt 5 0) "5^0 = 1") (assert= 1000 (expt 10 3) "10^3 = 1000") (let (r (expt 2 0.5)) (assert= true (and (> r 1.41) (< r 1.43)) "2^0.5 ≈ sqrt(2)"))) (deftest "quotient" (assert= 3 (quotient 13 4) "13/4 = 3") (assert= -3 (quotient -13 4) "-13/4 = -3 (truncate toward zero)") (assert= -3 (quotient 13 -4) "13/-4 = -3 (truncate toward zero)") (assert= 3 (quotient -13 -4) "-13/-4 = 3") (assert= 0 (quotient 0 5) "0/5 = 0")) (deftest "gcd" (assert= 6 (gcd 12 18) "gcd 12 18 = 6") (assert= 1 (gcd 7 13) "gcd 7 13 = 1 (coprime)") (assert= 4 (gcd 8 12) "gcd 8 12 = 4") (assert= 5 (gcd 0 5) "gcd 0 5 = 5") (assert= 6 (gcd -12 18) "gcd handles negatives")) (deftest "lcm" (assert= 12 (lcm 4 6) "lcm 4 6 = 12") (assert= 36 (lcm 12 18) "lcm 12 18 = 36") (assert= 0 (lcm 0 5) "lcm 0 5 = 0") (assert= 15 (lcm 3 5) "lcm 3 5 = 15")) (deftest "number->string" (assert= "42" (number->string 42) "integer to string") (assert= "0" (number->string 0) "zero to string") (assert= "-7" (number->string -7) "negative to string") (assert= "ff" (number->string 255 16) "255 in hex") (assert= "1111" (number->string 15 2) "15 in binary") (assert= "377" (number->string 255 8) "255 in octal") (assert= "z" (number->string 35 36) "35 in base 36")) (deftest "string->number" (assert= 42 (string->number "42") "string to integer") (assert= -7 (string->number "-7") "negative string to integer") (assert= 255 (string->number "ff" 16) "hex string") (assert= 15 (string->number "1111" 2) "binary string") (assert= 255 (string->number "377" 8) "octal string") (assert= nil (string->number "not-a-number") "invalid returns nil") (assert= nil (string->number "fg" 16) "invalid hex returns nil")) (deftest "numeric tower integration" (assert= true (< (abs (- (sin (asin 0.5)) 0.5)) 0.0001) "sin(asin(x)) = x") (assert= true (< (abs (- (cos (acos 0.5)) 0.5)) 0.0001) "cos(acos(x)) = x") (assert= true (< (abs (- (exp (log 2)) 2)) 0.0001) "exp(log(x)) = x") (assert= (* 12 18) (* (gcd 12 18) (lcm 12 18)) "gcd * lcm = a * b")))