Skip to content

Commit 07facd4

Browse files
authored
Add a precision assertion to BigMath test (#316)
* Add a precision assertion to BigMath test * Move precision assertion methods to test helper * Assert precision with multiple precision values: [50, 100, 150]
1 parent 0b85aa6 commit 07facd4

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

test/bigdecimal/helper.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,31 @@ def under_gc_stress
3636
ensure
3737
GC.stress = stress
3838
end
39+
40+
# Asserts that the calculation of the given block converges to some value
41+
# with precision specified by block parameter.
42+
43+
def assert_fixed_point_precision(&block)
44+
_assert_precision(:fixed_point, &block)
45+
end
46+
47+
def assert_relative_precision(&block)
48+
_assert_precision(:relative, &block)
49+
end
50+
51+
def _assert_precision(mode)
52+
expected = yield(200)
53+
[50, 100, 150].each do |n|
54+
value = yield(n)
55+
if mode == :fixed_point
56+
precision = -(value - expected).exponent
57+
elsif mode == :relative
58+
precision = -(value.div(expected, expected.precision) - 1).exponent
59+
else
60+
raise ArgumentError, "Unknown mode: #{mode}"
61+
end
62+
assert(value != expected, "Unable to estimate precision for exact value")
63+
assert(precision >= n, "Precision is not enough: #{precision} < #{n}")
64+
end
65+
end
3966
end

test/bigdecimal/test_bigmath.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ class TestBigMath < Test::Unit::TestCase
66
include TestBigDecimalBase
77
include BigMath
88
N = 20
9+
# SQRT in 116 (= 100 + double_fig) digits
10+
SQRT2 = BigDecimal("1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309123")
11+
SQRT3 = BigDecimal("1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067")
912
PINF = BigDecimal("+Infinity")
1013
MINF = BigDecimal("-Infinity")
1114
NAN = BigDecimal("NaN")
@@ -23,6 +26,11 @@ def test_sqrt
2326
assert_raise(FloatDomainError) {sqrt(BigDecimal("-1.0"), N)}
2427
assert_raise(FloatDomainError) {sqrt(NAN, N)}
2528
assert_raise(FloatDomainError) {sqrt(PINF, N)}
29+
assert_in_delta(SQRT2, sqrt(BigDecimal("2"), 100), BigDecimal("1e-100"))
30+
assert_in_delta(SQRT3, sqrt(BigDecimal("3"), 100), BigDecimal("1e-100"))
31+
assert_relative_precision {|n| sqrt(BigDecimal("2"), n) }
32+
assert_relative_precision {|n| sqrt(BigDecimal("2e-50"), n) }
33+
assert_relative_precision {|n| sqrt(BigDecimal("2e50"), n) }
2634
end
2735

2836
def test_sin
@@ -37,6 +45,13 @@ def test_sin
3745
assert_in_delta(0.0, sin(PI(N) * 21, N))
3846
assert_in_delta(0.0, sin(PI(N) * 30, N))
3947
assert_in_delta(-1.0, sin(PI(N) * BigDecimal("301.5"), N))
48+
assert_in_delta(BigDecimal('0.5'), sin(PI(100) / 6, 100), BigDecimal("1e-100"))
49+
assert_in_delta(SQRT3 / 2, sin(PI(100) / 3, 100), BigDecimal("1e-100"))
50+
assert_in_delta(SQRT2 / 2, sin(PI(100) / 4, 100), BigDecimal("1e-100"))
51+
assert_fixed_point_precision {|n| sin(BigDecimal("1"), n) }
52+
assert_fixed_point_precision {|n| sin(BigDecimal("1e-30"), n) }
53+
assert_fixed_point_precision {|n| sin(BigDecimal(PI(50)), n) }
54+
assert_fixed_point_precision {|n| sin(BigDecimal(PI(50) * 100), n) }
4055
end
4156

4257
def test_cos
@@ -51,20 +66,36 @@ def test_cos
5166
assert_in_delta(-1.0, cos(PI(N) * 21, N))
5267
assert_in_delta(1.0, cos(PI(N) * 30, N))
5368
assert_in_delta(0.0, cos(PI(N) * BigDecimal("301.5"), N))
69+
assert_in_delta(BigDecimal('0.5'), cos(PI(100) / 3, 100), BigDecimal("1e-100"))
70+
assert_in_delta(SQRT3 / 2, cos(PI(100) / 6, 100), BigDecimal("1e-100"))
71+
assert_in_delta(SQRT2 / 2, cos(PI(100) / 4, 100), BigDecimal("1e-100"))
72+
assert_fixed_point_precision {|n| cos(BigDecimal("1"), n) }
73+
assert_fixed_point_precision {|n| cos(BigDecimal(PI(50) / 2), n) }
74+
assert_fixed_point_precision {|n| cos(BigDecimal(PI(50) * 201 / 2), n) }
5475
end
5576

5677
def test_atan
5778
assert_equal(0.0, atan(BigDecimal("0.0"), N))
5879
assert_in_delta(Math::PI/4, atan(BigDecimal("1.0"), N))
5980
assert_in_delta(Math::PI/6, atan(sqrt(BigDecimal("3.0"), N) / 3, N))
6081
assert_in_delta(Math::PI/2, atan(PINF, N))
82+
assert_in_delta(PI(100) / 3, atan(SQRT3, 100), BigDecimal("1e-100"))
6183
assert_equal(BigDecimal("0.823840753418636291769355073102514088959345624027952954058347023122539489"),
6284
atan(BigDecimal("1.08"), 72).round(72), '[ruby-dev:41257]')
85+
assert_relative_precision {|n| atan(BigDecimal("2"), n)}
86+
assert_relative_precision {|n| atan(BigDecimal("1e-30"), n)}
87+
assert_relative_precision {|n| atan(BigDecimal("1e30"), n)}
6388
end
6489

6590
def test_log
6691
assert_equal(0, BigMath.log(BigDecimal("1.0"), 10))
6792
assert_in_epsilon(Math.log(10)*1000, BigMath.log(BigDecimal("1e1000"), 10))
93+
assert_in_epsilon(BigDecimal("2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862"),
94+
BigMath.log(BigDecimal("10"), 100), BigDecimal("1e-100"))
95+
assert_relative_precision {|n| BigMath.log(BigDecimal("2"), n) }
96+
assert_relative_precision {|n| BigMath.log(BigDecimal("1e-30") + 1, n) }
97+
assert_relative_precision {|n| BigMath.log(BigDecimal("1e-30"), n) }
98+
assert_relative_precision {|n| BigMath.log(BigDecimal("1e30"), n) }
6899
assert_raise(Math::DomainError) {BigMath.log(BigDecimal("0"), 10)}
69100
assert_raise(Math::DomainError) {BigMath.log(BigDecimal("-1"), 10)}
70101
assert_separately(%w[-rbigdecimal], <<-SRC)

0 commit comments

Comments
 (0)