diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2012-05-18 00:33:43 -0700 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2012-05-18 00:33:43 -0700 |
| commit | 631ab3536d0c2ed1e8b79d88aae0f3f11c3128c8 (patch) | |
| tree | dc8d798227fc7382813048b42303d9c9190a0039 | |
| parent | 2728f302976573f13b6942cc426fb840f597cb61 (diff) | |
| parent | d1f6f504d52ced12a9d58aa98b7ee158feef26ee (diff) | |
| download | mruby-631ab3536d0c2ed1e8b79d88aae0f3f11c3128c8.tar.gz mruby-631ab3536d0c2ed1e8b79d88aae0f3f11c3128c8.zip | |
Merge pull request #158 from pbosetti/tests
Minor edits to test suite and Math module
| -rw-r--r-- | src/math.c | 9 | ||||
| -rw-r--r-- | test/assert.rb | 2 | ||||
| -rw-r--r-- | test/t/math.rb | 33 |
3 files changed, 31 insertions, 13 deletions
diff --git a/src/math.c b/src/math.c index 73bcf5e2a..b0d911573 100644 --- a/src/math.c +++ b/src/math.c @@ -10,6 +10,8 @@ #define domain_error(msg) \ mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg); +#define MATH_TOLERANCE 1E-12 + /* math functions not provided under Microsoft Visual C++ */ #ifdef _MSC_VER #define asinh(x) log(x + sqrt(pow(x,2.0) + 1)) @@ -25,7 +27,7 @@ erfc(double x); ** Implementations of error functions ** credits to http://www.digitalmars.com/archives/cplusplus/3634.html */ -#define REL_ERROR 1E-12 + /* Implementation of Error function */ double erf(double x) @@ -45,7 +47,7 @@ erf(double x) term *= xsqr/j; sum += term/(2*j+1); ++j; - } while (fabs(term)/sum > REL_ERROR); + } while (fabs(term)/sum > MATH_TOLERANCE); return two_sqrtpi*sum; } @@ -77,7 +79,7 @@ erfc(double x) n += 0.5; q1 = q2; q2 = b/d; - } while (fabs(q1-q2)/q2 > REL_ERROR); + } while (fabs(q1-q2)/q2 > MATH_TOLERANCE); return one_sqrtpi*exp(-x*x)*q2; } @@ -610,6 +612,7 @@ mrb_init_math(mrb_state *mrb) struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); + mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(MATH_TOLERANCE)); #ifdef M_PI mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI)); #else diff --git a/test/assert.rb b/test/assert.rb index afc39fc24..54b50138e 100644 --- a/test/assert.rb +++ b/test/assert.rb @@ -22,7 +22,7 @@ end # iso : The ISO reference code of the feature # which will be tested by this # assertion -def assert(str = 'Assertion failed', iso = '') +def assert(str = 'Assertion failed', iso = 'No ISO') begin if(!yield) $asserts.push([str, iso]) diff --git a/test/t/math.rb b/test/t/math.rb index 0f42e7d49..a9c7e7fb7 100644 --- a/test/t/math.rb +++ b/test/t/math.rb @@ -1,18 +1,19 @@ ## # Math Test -MATH_TOLERANCE = 1E-12 +## +# Performs fuzzy check for equality on methods returning floats +# on the basis of the Math::TOLERANCE constant. def check(a,b) a = a.to_f b = b.to_f if a.finite? and b.finite? - (a-b).abs < MATH_TOLERANCE + (a-b).abs < Math::TOLERANCE else true end end - assert('Math.sin 0') do check(Math.sin(0), 0) end @@ -26,12 +27,13 @@ assert('Fundamental trig identities') do result = true N = 15 N.times do |i| - a = Math::PI / N * i - s = Math.sin(a) - c = Math.cos(a) - t = Math.tan(a) - result &= check(s, Math.cos(Math::PI / 2 - a)) - result &= check(t, 1 / Math.tan(Math::PI / 2 - a)) + a = Math::PI / N * i + ca = Math::PI / 2 - a + s = Math.sin(a) + c = Math.cos(a) + t = Math.tan(a) + result &= check(s, Math.cos(ca)) + result &= check(t, 1 / Math.tan(ca)) result &= check(s ** 2 + c ** 2, 1) result &= check(t ** 2 + 1, (1/c) ** 2) result &= check((1/t) ** 2 + 1, (1/s) ** 2) @@ -101,3 +103,16 @@ assert('Math.hypot') do check(Math.hypot(3, 4), 5.0) end +assert('Math.frexp 1234') do + n = 1234 + fraction, exponent = Math.frexp(n) + check(Math.ldexp(fraction, exponent), n) +end + +assert('Math.erf 1') do + check(Math.erf(1), 0.842700792949715) +end + +assert('Math.erfc 1') do + check(Math.erfc(1), 0.157299207050285) +end |
