| 1 | (* Auxiliary functions for test cases *) |
| 2 | |
| 3 | infix 1 seq |
| 4 | fun e1 seq e2 = e2; |
| 5 | fun check b = if b then "OK" else "WRONG"; |
| 6 | fun check' f = (if f () then "OK" else "WRONG") handle _ => "EXN"; |
| 7 | |
| 8 | fun range (from, to) p = |
| 9 | let open Int |
| 10 | in |
| 11 | (from > to) orelse (p from) andalso (range (from+1, to) p) |
| 12 | end; |
| 13 | |
| 14 | fun checkrange bounds = check o range bounds; |
| 15 | |
| 16 | fun tst0 s s' = print (s ^ " \t" ^ s' ^ "\n"); |
| 17 | fun tst s b = tst0 s (check b); |
| 18 | fun tst' s f = tst0 s (check' f); |
| 19 | |
| 20 | fun tstrange s bounds = (tst s) o range bounds |
| 21 | |
| 22 | (* test/math.sml |
| 23 | PS 1995-02-25, 1996-04-01, 1997-03-07 |
| 24 | *) |
| 25 | |
| 26 | val _ = print "\nFile math.sml: Testing structure Math...\n" |
| 27 | |
| 28 | local |
| 29 | open Math |
| 30 | val MAXDOUBLE = 8.98846567431157E307; |
| 31 | val MINDOUBLE = 4.94065645841246544E~324 |
| 32 | val PI = 3.14159265358979323846; |
| 33 | val E = 2.7182818284590452354; |
| 34 | |
| 35 | val eps = 1E~8 |
| 36 | infix 4 === |
| 37 | fun x === y = |
| 38 | abs (x - y) <= eps orelse abs(x-y) <= eps * (abs x + abs y) |
| 39 | |
| 40 | fun check1 (opr, a, r) = if opr a === r then "OK" else "WRONG" |
| 41 | fun check2 (opr, a1, a2, r) = |
| 42 | if opr(a1, a2) === r then "OK" else "WRONG" |
| 43 | fun tst1 s (opr, a, r) = tst0 s (check1 (opr, a, r)) |
| 44 | fun tst2 s (opr, a1, a2, r) = tst0 s (check2 (opr, a1, a2, r)) |
| 45 | |
| 46 | val test0a = tst "test0a" (PI === pi); |
| 47 | val test0b = tst "test0b" (E === e); |
| 48 | |
| 49 | val test1a = tst1 "test1a" (sqrt, 64.0, 8.0); |
| 50 | val test1b = tst1 "test1b" (sqrt, 0.0, 0.0); |
| 51 | val test1c = tst0 "test1c" (if Real.isNan(sqrt ~1.0) then "OK" else "WRONG") |
| 52 | |
| 53 | val test2a = tst1 "test2a" (sin, 0.0, 0.0); |
| 54 | val test2b = tst1 "test2b" (sin, pi/2.0, 1.0); |
| 55 | val test2c = tst1 "test2c" (sin, pi, 0.0); |
| 56 | val test2d = tst1 "test2d" (sin, 3.0*pi/2.0, ~1.0); |
| 57 | |
| 58 | val test3a = tst1 "test3a" (cos, 0.0, 1.0); |
| 59 | val test3b = tst1 "test3b" (cos, pi/2.0, 0.0); |
| 60 | val test3c = tst1 "test3c" (cos, pi, ~1.0); |
| 61 | val test3d = tst1 "test3d" (cos, 3.0*pi/2.0, 0.0); |
| 62 | |
| 63 | val test4a = tst1 "test4a" (tan, 0.0, 0.0); |
| 64 | val test4b = tst1 "test4b" (tan, pi/4.0, 1.0); |
| 65 | val test4c = tst1 "test4c" (tan, pi, 0.0); |
| 66 | val test4d = tst1 "test4d" (tan, 3.0*pi/4.0, ~1.0); |
| 67 | val test4e = tst1 "test4e" (tan, ~pi/4.0, ~1.0); |
| 68 | val test4f = tst "test4f" ((abs(tan (pi/2.0)) > 1E8) handle _ => true); |
| 69 | val test4g = tst "test4g" ((abs(tan (~pi/2.0)) > 1E8) handle _ => true); |
| 70 | |
| 71 | val test5a = tst1 "test5a" (asin, 0.0, 0.0); |
| 72 | val test5b = tst1 "test5b" (asin, 1.0, pi/2.0); |
| 73 | val test5c = tst1 "test5c" (asin, ~1.0, ~pi/2.0); |
| 74 | val test5d = tst0 "test5d" (if Real.isNan(asin 1.1) then "OK" else "WRONG") |
| 75 | val test5e = tst0 "test5e" (if Real.isNan(asin ~1.1) then "OK" else "WRONG") |
| 76 | |
| 77 | val test6a = tst1 "test6a" (acos, 1.0, 0.0); |
| 78 | val test6b = tst1 "test6b" (acos, 0.0, pi/2.0); |
| 79 | val test6c = tst1 "test6c" (acos, ~1.0, pi); |
| 80 | val test6d = tst0 "test6d" (if Real.isNan(acos 1.1) then "OK" else "WRONG") |
| 81 | val test6e = tst0 "test6e" (if Real.isNan(acos ~1.1) then "OK" else "WRONG") |
| 82 | |
| 83 | val test7a = tst1 "test7a" (atan, 0.0, 0.0); |
| 84 | val test7b = tst1 "test7b" (atan, 1.0, pi/4.0); |
| 85 | val test7c = tst1 "test7c" (atan, ~1.0, ~pi/4.0); |
| 86 | val test7d = tst1 "test7d" (atan, 1E8, pi/2.0); |
| 87 | val test7e = tst1 "test7e" (atan, ~1E8, ~pi/2.0); |
| 88 | |
| 89 | (* atan2 -- here I am in doubt over the argument order, since the New |
| 90 | Basis document is inconsistent with itself and with atan2 in the C |
| 91 | libraries. *) |
| 92 | |
| 93 | val test8a = tst2 "test8a" (atan2, 0.0, 0.0, 0.0); |
| 94 | val test8b = tst2 "test8b" (atan2, 1.0, 0.0, pi/2.0); |
| 95 | val test8c = tst2 "test8c" (atan2, ~1.0, 0.0, ~pi/2.0); |
| 96 | val test8d = tst2 "test8d" (atan2, 1.0, 1.0, pi/4.0); |
| 97 | val test8e = tst2 "test8e" (atan2, ~1.0, 1.0, ~pi/4.0); |
| 98 | val test8f = tst2 "test8f" (atan2, ~1.0, ~1.0, ~3.0*pi/4.0); |
| 99 | val test8g = tst2 "test8g" (atan2, 1.0, ~1.0, 3.0*pi/4.0); |
| 100 | val test8h = tst2 "test8h" (atan2, 1E8, 1.0, pi/2.0); |
| 101 | val test8i = tst2 "test8i" (atan2, ~1E8, 1.0, ~pi/2.0); |
| 102 | val test8j = tst2 "test8j" (atan2, 1.0, 1E8, 0.0); |
| 103 | val test8k = tst2 "test8k" (atan2, 1.0, ~1E8, pi); |
| 104 | val test8l = tst2 "test8l" (atan2, ~1.0, ~1E8, ~pi); |
| 105 | |
| 106 | val test9a = tst1 "test9a" (exp, 0.0, 1.0); |
| 107 | val test9b = tst1 "test9b" (exp, 1.0, e); |
| 108 | val test9c = tst1 "test9c" (exp, ~1.0, 1.0/e); |
| 109 | |
| 110 | val test10a = tst1 "test10a" (ln, 1.0, 0.0); |
| 111 | val test10b = tst1 "test10b" (ln, e, 1.0); |
| 112 | val test10c = tst1 "test10c" (ln, 1.0/e, ~1.0); |
| 113 | val test10d = tst0 "test10d" (if Real.==(ln 0.0,Real.negInf) then "OK" else "WRONG") |
| 114 | val test10e = tst0 "test10e" (if Real.isNan(ln ~1.0) then "OK" else "WRONG") |
| 115 | val test10f = tst0 "test10f" (if Real.==(ln Real.posInf, Real.posInf) then "OK" else "WRONG") |
| 116 | val test10g = tst0 "test10g" (if Real.==(Real.posInf, Real.posInf) then "OK" else "WRONG") |
| 117 | |
| 118 | val test12a = tst2 "test12a" (pow, 0.0, 0.0, 1.0); (* arbitrary, might be 0.0 *) |
| 119 | val test12b = tst2 "test12b" (pow, 7.0, 0.0, 1.0); |
| 120 | val test12c = tst2 "test12c" (pow, 0.0, 7.0, 0.0); |
| 121 | val test12d = tst2 "test12d" (pow, 64.0, 0.5, 8.0); |
| 122 | val test12e = tst2 "test12e" (pow, ~9.0, 2.0, 81.0); |
| 123 | val test12f = tst2 "test12f" (pow, 10.0, ~2.0, 0.01); |
| 124 | val test12g = tst2 "test12g" (pow, ~10.0, ~2.0, 0.01); |
| 125 | val test12h = tst2 "test12h" (pow, 0.0, 0.5, 0.0); |
| 126 | val test12i = tst2 "test12i" (pow, 0.4, ~2.0, 6.25); |
| 127 | |
| 128 | (*we do not follow the Basis Library specification exactly here, but rather follow math.h |
| 129 | val test12j = tst0 "test12j" (if Real.==(pow(0.0, ~1.0),Real.posInf) then "OK" else "WRONG") |
| 130 | val test12k = tst0 "test12k" (if Real.==(pow(0.0, ~0.5),Real.posInf) then "OK" else "WRONG") |
| 131 | *) |
| 132 | val test12l = tst0 "test12l" (if Real.isNan(pow(~1.0, 1.1)) then "OK" else "WRONG") |
| 133 | val test12m = tst0 "test12m" (if Real.isNan(pow(~1.0, 0.5)) then "OK" else "WRONG") |
| 134 | (* sweeks removed 12n because it fails on FreeBSD on x86, apparently due to a |
| 135 | * 64 bit vs 80 bit issue. |
| 136 | *) |
| 137 | (* val test12n = tst0 "test12n" (if Real.==(pow(3.0, 1000000.0),Real.posInf) then "OK" else "WRONG") *) (* not in basis lib spec.*) |
| 138 | val test13a = tst1 "test13a" (log10, 1.0, 0.0); |
| 139 | val test13b = tst1 "test13b" (log10, 10.0, 1.0); |
| 140 | val test13c = tst1 "test13c" (log10, 100.0, 2.0); |
| 141 | val test13d = tst1 "test13d" (log10, 0.1, ~1.0); |
| 142 | val test13e = tst1 "test13e" (log10, 0.01, ~2.0); |
| 143 | |
| 144 | val check14a = tst1 "test14a" (sinh, 0.0, 0.0); |
| 145 | val check14b = tst1 "test14b" (sinh, 1.0, 1.17520119364); |
| 146 | val check14c = tst1 "test14c" (sinh, ~1.0, ~1.17520119364); |
| 147 | val check14d = tst1 "test14d" (sinh, 2.0, 3.62686040785); |
| 148 | val check14e = tst1 "test14e" (sinh, ~2.0, ~3.62686040785); |
| 149 | |
| 150 | val check15a = tst1 "test15a" (cosh, 0.0, 1.0); |
| 151 | val check15b = tst1 "test15b" (cosh, 1.0, 1.54308063482); |
| 152 | val check15c = tst1 "test15c" (cosh, ~1.0, 1.54308063482); |
| 153 | val check15d = tst1 "test15d" (cosh, 2.0, 3.76219569108); |
| 154 | val check15e = tst1 "test15e" (cosh, ~2.0, 3.76219569108); |
| 155 | |
| 156 | val check16a = tst1 "test16a" (tanh, 0.0, 0.0); |
| 157 | val check16b = tst1 "test16b" (tanh, 1.0, 0.761594155956); |
| 158 | val check16c = tst1 "test16c" (tanh, ~1.0, ~0.761594155956); |
| 159 | val check16d = tst1 "test16d" (tanh, 2.0, 0.964027580076); |
| 160 | val check16e = tst1 "test16e" (tanh, ~2.0, ~0.964027580076); |
| 161 | val check16f = tst1 "test16f" (tanh, 100.0, 1.0); |
| 162 | val check16g = tst1 "test16g" (tanh, ~100.0, ~1.0); |
| 163 | in |
| 164 | end |