/
test_big_decimal.rb
209 lines (174 loc) · 8.35 KB
/
test_big_decimal.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
require 'test/unit'
require 'bigdecimal'
class TestBigDecimal < Test::Unit::TestCase
def test_bad_to_s_format_strings
bd = BigDecimal.new("1")
assert_equal("0.1E1", bd.to_s)
assert_equal("+0.1E1", bd.to_s("+-2"))
end
def test_no_singleton_methods_on_bigdecimal
num = BigDecimal.new("0.001")
assert_raise(TypeError) { class << num ; def amethod ; end ; end }
assert_raise(TypeError) { def num.amethod ; end }
end
def test_can_instantiate_big_decimal
assert_nothing_raised {BigDecimal.new("4")}
assert_nothing_raised {BigDecimal.new("3.14159")}
end
def test_can_implicitly_instantiate_big_decimal
# JRUBY-153 issues
assert_nothing_raised {BigDecimal("4")}
assert_nothing_raised {BigDecimal("3.14159")}
end
def test_reject_arguments_not_responding_to_to_str
assert_raise(TypeError) { BigDecimal.new(4) }
assert_raise(TypeError) { BigDecimal.new(3.14159) }
assert_raise(TypeError) { BigDecimal(4) }
assert_raise(TypeError) { BigDecimal(3.14159) }
end
def test_alphabetic_args_return_zero
assert_equal( BigDecimal("0.0"), BigDecimal("XXX"),
'Big Decimal objects instanitiated with a value that starts
with a letter should have a value of 0.0' )
end
class X
def to_str; "3.14159" end
end
def test_can_accept_arbitrary_objects_as_arguments
# as log as the object has a #to_str method...
x = X.new
assert_nothing_raised { BigDecimal.new(x) }
assert_nothing_raised { BigDecimal(x) }
end
require "bigdecimal/newton"
include Newton
class Function
def initialize()
@zero = BigDecimal::new("0.0")
@one = BigDecimal::new("1.0")
@two = BigDecimal::new("2.0")
@ten = BigDecimal::new("10.0")
@eps = BigDecimal::new("1.0e-16")
end
def zero;@zero;end
def one ;@one ;end
def two ;@two ;end
def ten ;@ten ;end
def eps ;@eps ;end
def values(x) # <= defines functions solved
f = []
f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0
f2 = x[0] - x[1] # f2 = x - y => 0
f <<= f1
f <<= f2
f
end
end
def test_newton_extension
f = BigDecimal::limit(100)
f = Function.new
x = [f.zero,f.zero] # Initial values
n = nlsolve(f,x)
expected = [BigDecimal('0.1000000000262923315461642086010446338567975310185638386446002778855192224707966221794469725479649528E1'),
BigDecimal('0.1000000000262923315461642086010446338567975310185638386446002778855192224707966221794469725479649528E1')]
assert_equal expected, x
end
require "bigdecimal/math.rb"
include BigMath
def test_math_extension
expected = BigDecimal('0.31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066453462141417033006060218E1')
# this test fails under C Ruby
# ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.9.1]
assert_equal expected, PI(100)
zero= BigDecimal("0")
one = BigDecimal("1")
two = BigDecimal("2")
three = BigDecimal("3")
assert_equal one * 1, one
assert_equal one / 1, one
assert_equal one + 1, two
assert_equal one - 1, zero
assert_equal zero, one % 1
assert_equal one, three % two
assert_equal BigDecimal("0.2"), BigDecimal("2.2") % two
assert_equal BigDecimal("0.003"), BigDecimal("15.993") % BigDecimal("15.99")
assert_equal 1*one, one
assert_equal 1/one, one
assert_equal 1+one, BigDecimal("2")
assert_equal 1-one, BigDecimal("0")
assert_equal one * 1.0, 1.0
assert_equal one / 1.0, 1.0
assert_equal one + 1.0, 2.0
assert_equal one - 1.0, 0.0
assert_equal 1.0*one, 1.0
assert_equal 1.0/one, 1.0
assert_equal 1.0+one, 2.0
assert_equal 1.0-one, 0.0
assert_equal("1.0", BigDecimal.new('1.0').to_s('F'))
assert_equal("0.0", BigDecimal.new('0.0').to_s)
assert_equal(BigDecimal("2"), BigDecimal("1.5").round)
assert_equal(BigDecimal("15"), BigDecimal("15").round)
assert_equal(BigDecimal("20"), BigDecimal("15").round(-1))
assert_equal(BigDecimal("0"), BigDecimal("15").round(-2))
assert_equal(BigDecimal("-10"), BigDecimal("-15").round(-1, BigDecimal::ROUND_CEILING))
assert_equal(BigDecimal("10"), BigDecimal("15").round(-1, BigDecimal::ROUND_HALF_DOWN))
assert_equal(BigDecimal("20"), BigDecimal("25").round(-1, BigDecimal::ROUND_HALF_EVEN))
assert_equal(BigDecimal("15.99"), BigDecimal("15.993").round(2))
assert_equal(BigDecimal("1"), BigDecimal("1.8").round(0, BigDecimal::ROUND_DOWN))
assert_equal(BigDecimal("2"), BigDecimal("1.2").round(0, BigDecimal::ROUND_UP))
assert_equal(BigDecimal("-1"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_CEILING))
assert_equal(BigDecimal("-2"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_FLOOR))
assert_equal(BigDecimal("-2"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_FLOOR))
assert_equal(BigDecimal("1"), BigDecimal("1.5").round(0, BigDecimal::ROUND_HALF_DOWN))
assert_equal(BigDecimal("2"), BigDecimal("1.5").round(0, BigDecimal::ROUND_HALF_EVEN))
assert_equal(BigDecimal("2"), BigDecimal("2.5").round(0, BigDecimal::ROUND_HALF_EVEN))
end
def test_big_decimal_power
n = BigDecimal("10")
assert_equal(n.power(0), BigDecimal("1"))
assert_equal(n.power(1), n)
assert_equal(n.power(2), BigDecimal("100"))
assert_equal(n.power(-1), BigDecimal("0.1"))
assert_raises(TypeError) { n.power(1.1) }
end
def test_big_decimal_mode
# Accept valid arguments to #mode
assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW,true)
assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW,false)
# Reject invalid arguments to #mode
assert_raises(TypeError) { BigDecimal.mode(true) } # first argument must be a Fixnum
assert_raises(TypeError) { BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, 1) } # second argument must be [true|false]
assert_raises(TypeError) { BigDecimal.mode(512) } # first argument must be == 256, or return non-zero when AND-ed with 255
# exception mode defaults to 0
assert_equal 0, BigDecimal.mode(1) # value of first argument doesn't matter when retrieving the current exception mode, as long as it's a Fixnum <= 255
# set and clear a single exception mode
assert_equal BigDecimal::EXCEPTION_INFINITY, BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
assert_equal 0, BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
assert_equal BigDecimal::EXCEPTION_NaN, BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true)
assert_equal 0, BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
# set a composition of exception modes separately, make sure the final result is the composited value
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true)
assert_equal BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)
# reset the exception mode to 0 for the following tests
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
# set a composition of exception modes with one call and retrieve it using the retrieval idiom
# note: this is to check compatibility with MRI, which currently sets only the last mode
# it checks for
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, true)
assert_equal BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)
# rounding mode defaults to 0
assert_equal 0, BigDecimal.mode(BigDecimal::ROUND_MODE)
# make sure each setting complete replaces any previous setting
[BigDecimal::ROUND_UP, BigDecimal::ROUND_DOWN, BigDecimal::ROUND_CEILING, BigDecimal::ROUND_FLOOR,
BigDecimal::ROUND_HALF_UP, BigDecimal::ROUND_HALF_DOWN, BigDecimal::ROUND_HALF_EVEN].each do |mode|
assert_equal mode, BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
end
# reset rounding mode to 0 for following tests
BigDecimal.mode(BigDecimal::ROUND_MODE, 0)
assert_raises(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, true) } # second argument must be a Fixnum
assert_raises(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 7) } # any Fixnum >= 7 should trigger this error, as the valid rounding modes are currently [0..6]
end
end