decimal 0.0.2 → 0.0.90.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +2 -2
- data/INSTALL +1 -2
- data/README +57 -1
- data/README.1st +1 -0
- data/TODO +25 -0
- data/decimal.c +927 -446
- data/decimal.gemspec +9 -5
- data/depend +1 -1
- data/extconf.rb +14 -0
- data/inum18.h +82 -8
- data/inum191.h +350 -0
- data/inum192.h +332 -0
- data/lib/decimal.rb +2 -0
- data/lib/decimal/math.rb +566 -0
- data/ruby18compat.h +55 -0
- data/test_decimal.rb +546 -0
- metadata +37 -11
data/ruby18compat.h
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
/*
|
2
|
+
* ruby18compat.h - write Ruby 1.8 compatible extention library
|
3
|
+
* with 1.9 style
|
4
|
+
*
|
5
|
+
* This program is under public domain.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef RBIGNUM_SIGN
|
9
|
+
#define RBIGNUM_SIGN(x) RBIGNUM(x)->sign
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#ifndef RBIGNUM_NEGATIVE_P
|
13
|
+
#define RBIGNUM_NEGATIVE_P(x) (!RBIGNUM_SIGN(x))
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#ifndef RUBY_CRITICAL
|
17
|
+
#define RUBY_CRITICAL(statements) do {statements;} while (0)
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#ifndef RB_NUM_COERCE_FUNCS_NEED_OPID
|
21
|
+
#define rb_num_coerce_bin(x, y, id) rb_num_coerce_bin(x, y)
|
22
|
+
#define rb_num_coerce_cmp(x, y, id) rb_num_coerce_cmp(x, y)
|
23
|
+
#define rb_num_coerce_relop(x, y, id) rb_num_coerce_relop(x, y)
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#ifndef HAVE_RB_BIG_DIV
|
27
|
+
#define rb_big_div(x, y) (RARRAY_PTR(rb_big_divmod(x, y))[0])
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#ifndef HAVE_RB_BIG_MODULO
|
31
|
+
#define rb_big_modulo(x, y) (RARRAY_PTR(rb_big_divmod(x, y))[1])
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#ifndef NAN
|
35
|
+
#if BYTE_ORDER == LITTLE_ENDIAN
|
36
|
+
static const unsigned char rb_nan[] = "\x00\x00\xc0\x7f";
|
37
|
+
#else
|
38
|
+
static const unsigned char rb_nan[] = "\x7f\xc0\x00\x00";
|
39
|
+
#endif
|
40
|
+
#define NAN (*(float *)rb_nan)
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#ifndef INFINITY
|
44
|
+
#if BYTE_ORDER == LITTLE_ENDIAN
|
45
|
+
static const unsigned char rb_infinity[] = "\x00\x00\x80\x7f";
|
46
|
+
#else
|
47
|
+
static const unsigned char rb_infinity[] = "\x7f\x80\x00\x00";
|
48
|
+
#endif
|
49
|
+
#define INFINITY (*(float *)rb_infinity)
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#ifndef HAVE_RB_USASCII_STR_NEW
|
53
|
+
#define rb_usascii_str_new rb_str_new
|
54
|
+
#define rb_usascii_str_new_cstr rb_str_new2
|
55
|
+
#endif
|
data/test_decimal.rb
ADDED
@@ -0,0 +1,546 @@
|
|
1
|
+
require 'decimal'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestDecimal < Test::Unit::TestCase
|
5
|
+
ONE = Decimal(1)
|
6
|
+
ZERO = Decimal(0)
|
7
|
+
INFINITY = Decimal::INFINITY
|
8
|
+
NAN = Decimal::NAN
|
9
|
+
|
10
|
+
def assert_nan(a, *rest)
|
11
|
+
rest = ["not nan: #{a.inspect}"] if rest.empty?
|
12
|
+
assert(a.nan?, *rest)
|
13
|
+
end
|
14
|
+
|
15
|
+
def assert_infinity(a, *rest)
|
16
|
+
rest = ["not infinity: #{a.inspect}"] if rest.empty?
|
17
|
+
assert(a.infinite?, *rest)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_initialize
|
21
|
+
assert_nothing_raised {Decimal(1)}
|
22
|
+
assert_nothing_raised {Decimal(2**64)}
|
23
|
+
assert_nothing_raised {Decimal("1")}
|
24
|
+
assert_nothing_raised {Decimal("1.1")}
|
25
|
+
assert_nothing_raised {Decimal("1e10")}
|
26
|
+
assert_nothing_raised {Decimal("299_792_458")}
|
27
|
+
assert_nothing_raised {Decimal("2.99_792_458e8")}
|
28
|
+
assert_raise(ArgumentError) {Decimal(1.1)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_stringize
|
32
|
+
assert_equal("1", ONE.to_s)
|
33
|
+
assert_equal("1", Decimal("1").to_s)
|
34
|
+
assert_equal("1.1", Decimal("1.1").to_s)
|
35
|
+
assert_equal("18446744073709551616", Decimal(2**64).to_s)
|
36
|
+
assert_equal("10000000000", Decimal("1e10").to_s)
|
37
|
+
assert_equal("299792458", Decimal("299_792_458").to_s)
|
38
|
+
assert_equal("299792458", Decimal("2.99_792_458e8").to_s)
|
39
|
+
assert_equal("Infinity", INFINITY.to_s)
|
40
|
+
assert_equal("-Infinity", (-INFINITY).to_s)
|
41
|
+
assert_equal("NaN", NAN.to_s)
|
42
|
+
|
43
|
+
assert_equal("Decimal(1)", ONE.inspect)
|
44
|
+
assert_equal("Decimal(1)", Decimal("1").inspect)
|
45
|
+
assert_equal("Decimal(1.1)", Decimal("1.1").inspect)
|
46
|
+
assert_equal("Decimal(18446744073709551616)", Decimal(2**64).inspect)
|
47
|
+
assert_equal("Decimal(10000000000)", Decimal("1e10").inspect)
|
48
|
+
assert_equal("Decimal(299792458)", Decimal("299_792_458").inspect)
|
49
|
+
assert_equal("Decimal(299792458)", Decimal("2.99_792_458e8").inspect)
|
50
|
+
assert_equal("Decimal(Infinity)", INFINITY.inspect)
|
51
|
+
assert_equal("Decimal(-Infinity)", (-INFINITY).inspect)
|
52
|
+
assert_equal("Decimal(NaN)", NAN.inspect)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_coerce
|
56
|
+
assert_equal([Decimal(2), ONE], ONE.coerce(2))
|
57
|
+
assert_equal([Decimal(2), ONE], ONE.coerce(Decimal(2)))
|
58
|
+
assert_raise(TypeError) {ONE.coerce(2.5)}
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_uminus
|
62
|
+
assert_equal(Decimal(-1), -ONE)
|
63
|
+
assert_equal(Decimal(-(2**64)), -Decimal(2**64))
|
64
|
+
assert(Decimal("-0").eql?(-ZERO)) # should use Decimal#eql?,
|
65
|
+
assert(ZERO.eql?(-Decimal("-0"))) # because `-0 == 0`
|
66
|
+
assert(!ZERO.eql?(-ZERO))
|
67
|
+
assert(!Decimal("-0").eql?(-Decimal("-0")))
|
68
|
+
assert_not_equal(-NAN, -NAN)
|
69
|
+
assert_equal(Decimal(-1).divide(0), -INFINITY)
|
70
|
+
assert_equal(INFINITY, -(Decimal(-1).divide(0)))
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_add
|
74
|
+
assert_equal(Decimal("1.1"), Decimal("0.1") + 1)
|
75
|
+
sum = 0
|
76
|
+
10.times {sum += Decimal("0.1")}
|
77
|
+
assert_equal(ONE, sum)
|
78
|
+
assert_raise(TypeError) {Decimal("0.1") + 1.0}
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_sub
|
82
|
+
assert_equal(Decimal("0.1"), Decimal("1.1") - 1)
|
83
|
+
sum = 0
|
84
|
+
10.times {sum -= Decimal("0.1")}
|
85
|
+
assert_equal(Decimal(-1), sum)
|
86
|
+
assert_raise(TypeError) {Decimal("0.1") - 1.0}
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_mul
|
90
|
+
assert_equal(ONE, Decimal("0.1") * 10)
|
91
|
+
sum = ONE
|
92
|
+
10.times {sum *= Decimal("0.1")}
|
93
|
+
assert_equal(Decimal("0.0000000001"), sum)
|
94
|
+
assert_raise(TypeError) {Decimal("0.1") * 1.0}
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_div
|
98
|
+
assert_equal(Decimal("0.1"), ONE.divide(10, 1))
|
99
|
+
sum = Decimal(1 << 10)
|
100
|
+
10.times {sum = sum.divide(2)}
|
101
|
+
assert_equal(ONE, sum)
|
102
|
+
assert_raise(TypeError) {Decimal("0.1").divide(1.0)}
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_idiv
|
106
|
+
assert_equal(2, Decimal("11.5").div(4))
|
107
|
+
assert_equal(-3, Decimal("11.5").div(-4))
|
108
|
+
assert_equal(-3, Decimal("-11.5").div(4))
|
109
|
+
assert_equal(2, Decimal("-11.5").div(-4))
|
110
|
+
assert_raise(TypeError) {Decimal(11).div(4.0)}
|
111
|
+
assert_nan(Decimal::NAN.div(1))
|
112
|
+
assert_nan(Decimal(1).div(Decimal::NAN))
|
113
|
+
assert_nan(Decimal::INFINITY.div(1))
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_mod
|
117
|
+
assert_equal(0, Decimal(1) % 1)
|
118
|
+
assert_equal(Decimal("3.5"), Decimal("11.5") % 4)
|
119
|
+
assert_equal(Decimal("-0.5"), Decimal("11.5") % -4)
|
120
|
+
assert_equal(Decimal("0.5"), Decimal("-11.5") % 4)
|
121
|
+
assert_equal(Decimal("-3.5"), Decimal("-11.5") % -4)
|
122
|
+
assert_raise(TypeError) {Decimal(11) % 4.0}
|
123
|
+
assert_nan(Decimal::NAN % 1)
|
124
|
+
assert_nan(Decimal(1) % Decimal::NAN)
|
125
|
+
assert_nan(Decimal::INFINITY % 1)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_pow
|
129
|
+
assert_equal(1 << 10, Decimal(2) ** 10)
|
130
|
+
assert_equal(1, ONE ** 10)
|
131
|
+
assert_equal(Decimal("0.0000000001"), Decimal("0.1") ** 10)
|
132
|
+
assert_raise(TypeError) {ONE ** 10.0}
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_eq
|
136
|
+
assert_equal(ONE, 1)
|
137
|
+
assert_equal(Decimal("1.0"), 1)
|
138
|
+
assert_equal(Decimal("100e-2"), 1)
|
139
|
+
assert_equal(Decimal("0.01e2"), 1)
|
140
|
+
|
141
|
+
assert(ONE.eql?(ONE))
|
142
|
+
assert((-ONE).eql?(-ONE))
|
143
|
+
assert(INFINITY.eql?(INFINITY))
|
144
|
+
assert((-INFINITY).eql?(-INFINITY))
|
145
|
+
assert(!ONE.eql?(Decimal("1.0")))
|
146
|
+
|
147
|
+
assert_not_equal(ONE, 2**32)
|
148
|
+
assert_not_equal(ONE, NAN)
|
149
|
+
assert_not_equal(ONE, nil)
|
150
|
+
assert_not_equal(ONE, 1.0)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_cmp
|
154
|
+
assert_equal(0, ONE <=> ONE)
|
155
|
+
assert_equal(1, ONE <=> ZERO)
|
156
|
+
assert_equal(-1, ZERO <=> ONE)
|
157
|
+
assert_equal(-1, ONE <=> Decimal(2))
|
158
|
+
assert_nil(ONE <=> nil)
|
159
|
+
assert_nil(ONE <=> NAN)
|
160
|
+
assert_nil(NAN <=> ONE)
|
161
|
+
assert_nil(ONE <=> 1.0)
|
162
|
+
|
163
|
+
assert_equal(0, ONE <=> 1)
|
164
|
+
assert_equal(1, ONE <=> 0)
|
165
|
+
assert_equal(-1, ONE <=> 2)
|
166
|
+
|
167
|
+
assert_equal(-1, ONE <=> 2**32)
|
168
|
+
|
169
|
+
assert_raise(ArgumentError) {ONE > nil}
|
170
|
+
assert_raise(ArgumentError) {ONE >= nil}
|
171
|
+
assert_raise(ArgumentError) {ONE < nil}
|
172
|
+
assert_raise(ArgumentError) {ONE <= nil}
|
173
|
+
|
174
|
+
assert_raise(ArgumentError) {ONE > 1.0}
|
175
|
+
assert_raise(ArgumentError) {ONE >= 1.0}
|
176
|
+
assert_raise(ArgumentError) {ONE < 1.0}
|
177
|
+
assert_raise(ArgumentError) {ONE <= 1.0}
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_hash
|
181
|
+
assert_equal(ONE.hash, ONE.hash)
|
182
|
+
assert_equal(ZERO.hash, ZERO.hash)
|
183
|
+
assert_equal(NAN.hash, NAN.hash)
|
184
|
+
assert_equal(INFINITY.hash, INFINITY.hash)
|
185
|
+
|
186
|
+
assert_not_equal(ONE.hash, Decimal("1.0").hash)
|
187
|
+
assert_not_equal(ZERO.hash, Decimal("0.0").hash)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_abs
|
191
|
+
assert_equal(Decimal(-1).abs, ONE)
|
192
|
+
assert_equal(Decimal(-(2**64)).abs, 2**64)
|
193
|
+
assert(Decimal("-0").abs.eql?(ZERO))
|
194
|
+
assert_equal((-INFINITY).abs, INFINITY)
|
195
|
+
assert_not_equal(NAN.abs, NAN)
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_divmod
|
199
|
+
assert_equal([2, Decimal("3.5")], Decimal("11.5").divmod(4))
|
200
|
+
assert_equal([-3, Decimal("-0.5")], Decimal("11.5").divmod(-4))
|
201
|
+
assert_equal([-3, Decimal("0.5")], Decimal("-11.5").divmod(4))
|
202
|
+
assert_equal([2, Decimal("-3.5")], Decimal("-11.5").divmod(-4))
|
203
|
+
assert_raise(TypeError) {Decimal(11).divmod(4.0)}
|
204
|
+
div, mod = Decimal::NAN.divmod(1)
|
205
|
+
assert_nan(div)
|
206
|
+
assert_nan(mod)
|
207
|
+
div, mod = Decimal(1).divmod(Decimal::NAN)
|
208
|
+
assert_nan(div)
|
209
|
+
assert_nan(mod)
|
210
|
+
div, mod = Decimal::INFINITY.divmod(1)
|
211
|
+
assert_nan(div)
|
212
|
+
assert_nan(mod)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_div
|
216
|
+
assert_equal(1, Decimal(1).div(1))
|
217
|
+
assert_equal(2, Decimal("11.5").div(4))
|
218
|
+
assert_equal(-3, Decimal("11.5").div(-4))
|
219
|
+
assert_equal(-3, Decimal("-11.5").div(4))
|
220
|
+
assert_equal(2, Decimal("-11.5").div(-4))
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_remainder
|
224
|
+
assert_equal(0, Decimal(1).remainder(1))
|
225
|
+
assert_equal(Decimal("3.5"), Decimal("11.5").remainder(4))
|
226
|
+
assert_equal(Decimal("3.5"), Decimal("11.5").remainder(-4))
|
227
|
+
assert_equal(Decimal("-3.5"), Decimal("-11.5").remainder(4))
|
228
|
+
assert_equal(Decimal("-3.5"), Decimal("-11.5").remainder(-4))
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_to_f
|
232
|
+
max, min = Float::MAX_10_EXP+10, Float::MIN_10_EXP-10
|
233
|
+
assert_equal(1.0/0.0, Decimal("1e#{max}").to_f)
|
234
|
+
assert_equal(-1.0/0.0, Decimal("-1e#{max}").to_f)
|
235
|
+
assert_equal("0.0", Decimal("1e#{min}").to_f.to_s)
|
236
|
+
assert_equal("-0.0", Decimal("-1e#{min}").to_f.to_s)
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_zero_scale
|
240
|
+
a, b, c, d = Decimal(0), Decimal("0.0"), Decimal("-0"), Decimal("-0.0")
|
241
|
+
assert_equal("0.0", (a + b).to_s)
|
242
|
+
assert_equal("-0.0", (c + d).to_s)
|
243
|
+
assert_equal("0.0", (a + d).to_s)
|
244
|
+
assert_equal("1.0", (Decimal("0.0")+Decimal(1)).to_s)
|
245
|
+
end
|
246
|
+
|
247
|
+
# math part
|
248
|
+
|
249
|
+
M = Decimal::Math
|
250
|
+
SCALE = Float::DIG * 2
|
251
|
+
PI = M.pi(SCALE*2)
|
252
|
+
def check(expected, actual)
|
253
|
+
expected = Decimal(expected).round(SCALE/2)
|
254
|
+
actual = Decimal(actual).round(SCALE/2)
|
255
|
+
assert_in_delta(expected, actual, Decimal("1e-#{SCALE/2}"))
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_math_atan2
|
259
|
+
#assert_raise(Math::DomainError) { Math.atan2(0, 0) }
|
260
|
+
#assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, Float::INFINITY) }
|
261
|
+
#assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, -Float::INFINITY) }
|
262
|
+
#assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, Float::INFINITY) }
|
263
|
+
#assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, -Float::INFINITY) }
|
264
|
+
check(0, M.atan2(0, 1, SCALE))
|
265
|
+
check(PI.divide(4, SCALE, :down), M.atan2(1, 1, SCALE))
|
266
|
+
check(PI.divide(2, SCALE, :down), M.atan2(1, 0, SCALE))
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_math_cos
|
270
|
+
check(1, M.cos(0, SCALE))
|
271
|
+
sqrt_2 = M.sqrt(2, SCALE)
|
272
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
273
|
+
check(ONE.divide(sqrt_2, SCALE, :half_up), M.cos(pi_q, SCALE))
|
274
|
+
check(0, M.cos(2 * pi_q, SCALE))
|
275
|
+
check(-1, M.cos(4 * pi_q, SCALE))
|
276
|
+
check(0, M.cos(6 * pi_q, SCALE))
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_math_sin
|
280
|
+
check(0, M.sin(0, SCALE))
|
281
|
+
sqrt_2 = M.sqrt(2, SCALE)
|
282
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
283
|
+
check(ONE.divide(sqrt_2, SCALE, :half_up), M.sin(pi_q, SCALE))
|
284
|
+
check(1, M.sin(2 * pi_q, SCALE))
|
285
|
+
check(0, M.sin(4 * pi_q, SCALE))
|
286
|
+
check(-1, M.sin(6 * pi_q, SCALE))
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_math_tan
|
290
|
+
check(0, M.tan(0, SCALE))
|
291
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
292
|
+
check(1, M.tan(pi_q, SCALE))
|
293
|
+
assert(M.tan(2 * pi_q, SCALE).abs > Decimal("1e#{SCALE}"))
|
294
|
+
check(0, M.tan(4 * pi_q, SCALE))
|
295
|
+
assert(M.tan(6 * pi_q, SCALE).abs > Decimal("1e#{SCALE}"))
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_math_acos
|
299
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
300
|
+
check(0 * pi_q, M.acos(1, SCALE))
|
301
|
+
sqrt_2 = M.sqrt(2, SCALE)
|
302
|
+
check(1 * pi_q, M.acos(ONE.divide(sqrt_2, SCALE, :half_up), SCALE))
|
303
|
+
check(2 * pi_q, M.acos(0, SCALE))
|
304
|
+
check(4 * pi_q, M.acos(-1, SCALE))
|
305
|
+
assert_raise(Errno::EDOM) {M.acos(+1 + Decimal("1e-#{SCALE*2}"), SCALE)} # XXX
|
306
|
+
assert_raise(Errno::EDOM) {M.acos(-1 - Decimal("1e-#{SCALE*2}"), SCALE)} # XXX
|
307
|
+
assert_raise(Errno::EDOM) {M.acos(2, SCALE)} # XXX
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_math_asin
|
311
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
312
|
+
check(0 * pi_q, M.asin(0, SCALE))
|
313
|
+
sqrt_2 = M.sqrt(2, SCALE)
|
314
|
+
check(1 * pi_q, M.asin(ONE.divide(sqrt_2, SCALE, :half_up), SCALE))
|
315
|
+
check(2 * pi_q, M.asin(1, SCALE))
|
316
|
+
check(-2 * pi_q, M.asin(-1, SCALE))
|
317
|
+
assert_raise(Errno::EDOM) {M.asin(+1 + Decimal("1e-#{SCALE*2}"), SCALE)} # XXX
|
318
|
+
assert_raise(Errno::EDOM) {M.asin(-1 - Decimal("1e-#{SCALE*2}"), SCALE)} # XXX
|
319
|
+
assert_raise(Errno::EDOM) {M.asin(2, SCALE)} # XXX
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_math_atan
|
323
|
+
pi_q = PI.divide(4, SCALE, :half_up)
|
324
|
+
check(0 * pi_q, M.atan(0, SCALE))
|
325
|
+
check(1 * pi_q, M.atan(1, SCALE))
|
326
|
+
check(2 * pi_q, M.atan(INFINITY, SCALE))
|
327
|
+
check(-1 * pi_q, M.atan(-1, SCALE))
|
328
|
+
end
|
329
|
+
|
330
|
+
E = M.e(SCALE*2)
|
331
|
+
E_INV = Decimal(1).divide(E, SCALE*2, :down)
|
332
|
+
def test_math_cosh
|
333
|
+
check(1, M.cosh(0, SCALE))
|
334
|
+
check((E ** 1 + E_INV ** 1).divide(2, SCALE, :down), M.cosh(1, SCALE))
|
335
|
+
check((E ** 2 + E_INV ** 2).divide(2, SCALE, :down), M.cosh(2, SCALE))
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_math_sinh
|
339
|
+
check(0, M.sinh(0, SCALE))
|
340
|
+
check((E ** 1 - E_INV ** 1).divide(2, SCALE, :down), M.sinh(1, SCALE))
|
341
|
+
check((E ** 2 - E_INV ** 2).divide(2, SCALE, :down), M.sinh(2, SCALE))
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_math_tanh
|
345
|
+
x, y = M.sinh(0, SCALE), M.cosh(0, SCALE)
|
346
|
+
check(x.divide(y, SCALE, :down), M.tanh(0, SCALE))
|
347
|
+
x, y = M.sinh(1, SCALE), M.cosh(1, SCALE)
|
348
|
+
check(x.divide(y, SCALE, :down), M.tanh(1, SCALE))
|
349
|
+
x, y = M.sinh(2, SCALE), M.cosh(2, SCALE)
|
350
|
+
check(x.divide(y, SCALE, :down), M.tanh(2, SCALE))
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_math_acosh
|
354
|
+
check(0, M.acosh(1, SCALE))
|
355
|
+
check(1, M.acosh((E ** 1 + E_INV ** 1).divide(2, SCALE, :down), SCALE))
|
356
|
+
check(2, M.acosh((E ** 2 + E_INV ** 2).divide(2, SCALE, :down), SCALE))
|
357
|
+
assert_raise(Errno::EDOM) {M.acosh(1 - Decimal("1e-1000"), SCALE)} # XXX
|
358
|
+
assert_raise(Errno::EDOM) {M.acosh(0, SCALE)} # XXX
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_math_asinh
|
362
|
+
check(0, M.asinh(0, SCALE))
|
363
|
+
check(1, M.asinh((E ** 1 - E_INV ** 1).divide(2, SCALE, :down), SCALE))
|
364
|
+
check(2, M.asinh((E ** 2 - E_INV ** 2).divide(2, SCALE, :down), SCALE))
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_math_atanh
|
368
|
+
x, y = M.sinh(0, SCALE), M.cosh(0, SCALE)
|
369
|
+
check(0, M.atanh(x.divide(y, SCALE, :down), SCALE))
|
370
|
+
x, y = M.sinh(1, SCALE), M.cosh(1, SCALE)
|
371
|
+
check(1, M.atanh(x.divide(y, SCALE, :down), SCALE))
|
372
|
+
x, y = M.sinh(2, SCALE), M.cosh(2, SCALE)
|
373
|
+
check(2, M.atanh(x.divide(y, SCALE, :down), SCALE))
|
374
|
+
#assert_nothing_raised { assert_infinity(Math.atanh(1)) }
|
375
|
+
#assert_nothing_raised { assert_infinity(-Math.atanh(-1)) }
|
376
|
+
assert_raise(Errno::EDOM) {M.atanh(+1 + Decimal("1e-1000"), SCALE)}
|
377
|
+
assert_raise(Errno::EDOM) {M.atanh(-1 - Decimal("1e-1000"), SCALE)}
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_math_exp_and_e
|
381
|
+
check(1, M.exp(0, SCALE))
|
382
|
+
check(M.sqrt(M.e(SCALE), SCALE), M.exp(Decimal("0.5"), SCALE))
|
383
|
+
check(M.e(SCALE), M.exp(1, SCALE))
|
384
|
+
check(M.e(SCALE) ** 2, M.exp(2, SCALE))
|
385
|
+
end
|
386
|
+
|
387
|
+
def test_math_log
|
388
|
+
check(0, M.log(1, SCALE))
|
389
|
+
check(1, M.log(M.e(SCALE), SCALE))
|
390
|
+
check(0, M.log(1, 10, SCALE))
|
391
|
+
check(1, M.log(10, 10, SCALE))
|
392
|
+
check(2, M.log(100, 10, SCALE))
|
393
|
+
assert_infinity(M.log(INFINITY, SCALE))
|
394
|
+
#assert_nothing_raised {assert_infinity(-M.log(+0, SCALE))} # really??
|
395
|
+
#assert_nothing_raised {assert_infinity(-M.log(-0, SCALE))} # (ditto)
|
396
|
+
assert_raise(Errno::EDOM) {M.log(-1, SCALE)} # XXX
|
397
|
+
assert_raise(TypeError) {M.log(1,:foo, SCALE)}
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_math_log2
|
401
|
+
check(0, M.log2(1, SCALE))
|
402
|
+
check(1, M.log2(2, SCALE))
|
403
|
+
check(2, M.log2(4, SCALE))
|
404
|
+
assert_equal(INFINITY, M.log2(INFINITY, SCALE))
|
405
|
+
#assert_nothing_raised {assert_infinity(-M.log2(+0, SCALE))} # XXX
|
406
|
+
#assert_nothing_raised {assert_infinity(-M.log2(-0, SCALE))} # XXX
|
407
|
+
assert_raise(Errno::EDOM) {M.log2(-1, SCALE)} # XXX
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_math_log10
|
411
|
+
check(0, M.log10(1, SCALE))
|
412
|
+
check(1, M.log10(10, SCALE))
|
413
|
+
check(2, M.log10(100, SCALE))
|
414
|
+
assert_equal(INFINITY, M.log10(INFINITY, SCALE))
|
415
|
+
#assert_nothing_raised {assert_infinity(-M.log10(+0, SCALE))} # XXX
|
416
|
+
#assert_nothing_raised {assert_infinity(-M.log10(-0, SCALE))} # XXX
|
417
|
+
assert_raise(Errno::EDOM) {M.log10(-1, SCALE)} # XXX
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_math_pi
|
421
|
+
check("3.141592653589793238", M.pi(SCALE))
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_math_sqrt
|
425
|
+
check(0, M.sqrt(0, SCALE))
|
426
|
+
check(1, M.sqrt(1, SCALE))
|
427
|
+
check(2, M.sqrt(4, SCALE))
|
428
|
+
assert_equal(INFINITY, M.sqrt(INFINITY, SCALE))
|
429
|
+
assert_equal("0.0", M.sqrt(Decimal("-0.0"), SCALE).to_s[0..2]) # insure it is +0.0, not -0.0
|
430
|
+
assert_raise(Errno::EDOM) {M.sqrt(-1, SCALE)} # XXX
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_math_frexp10
|
434
|
+
check(0, M.frexp10(0).first)
|
435
|
+
assert_equal(0, M.frexp10(0).last)
|
436
|
+
check("0.1", M.frexp10(Decimal("0.1")).first)
|
437
|
+
assert_equal(0, M.frexp10(Decimal("0.1")).last)
|
438
|
+
check("0.1", M.frexp10(1).first)
|
439
|
+
assert_equal(1, M.frexp10(1).last)
|
440
|
+
check("0.1", M.frexp10(10).first)
|
441
|
+
assert_equal(2, M.frexp10(10).last)
|
442
|
+
check("0.1", M.frexp10(100).first)
|
443
|
+
assert_equal(3, M.frexp10(100).last)
|
444
|
+
check("0.123", M.frexp10(Decimal("12.3")).first)
|
445
|
+
assert_equal(2, M.frexp10(Decimal("12.3")).last)
|
446
|
+
check("-0.123", M.frexp10(Decimal("-12.3")).first)
|
447
|
+
assert_equal(2, M.frexp10(Decimal("-12.3")).last)
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_math_ldexp10
|
451
|
+
check(0, M.ldexp10(0, 0))
|
452
|
+
check("0.1", M.ldexp10(Decimal("0.1"), 0))
|
453
|
+
check(1, M.ldexp10(Decimal("0.1"), 1))
|
454
|
+
check(10, M.ldexp10(Decimal("0.1"), 2))
|
455
|
+
check(100, M.ldexp10(Decimal("0.1"), 3))
|
456
|
+
check("0.123", M.ldexp10(Decimal("12.3"), -2))
|
457
|
+
check("-0.123", M.ldexp10(Decimal("-12.3"), -2))
|
458
|
+
end
|
459
|
+
|
460
|
+
def test_math_hypot
|
461
|
+
check(5, M.hypot(3, 4, SCALE))
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_math_erf
|
465
|
+
check(0, M.erf(0, SCALE))
|
466
|
+
check(1, M.erf(Decimal::INFINITY, SCALE))
|
467
|
+
check("0.842700792949715", M.erf(1, SCALE))
|
468
|
+
end
|
469
|
+
|
470
|
+
def test_math_erfc
|
471
|
+
check(1, M.erfc(0, SCALE))
|
472
|
+
check(0, M.erfc(Decimal::INFINITY, SCALE))
|
473
|
+
check("0.157299207050285", M.erfc(1, SCALE))
|
474
|
+
end
|
475
|
+
|
476
|
+
SQRT_PI = M.sqrt(PI, SCALE*2)
|
477
|
+
def test_math_gamma
|
478
|
+
check((4 * SQRT_PI).divide(3, SCALE, :down),
|
479
|
+
M.gamma(Decimal("-1.5"), SCALE))
|
480
|
+
check(-2 * SQRT_PI, M.gamma(Decimal("-0.5"), SCALE))
|
481
|
+
check(SQRT_PI, M.gamma(Decimal("0.5"), SCALE))
|
482
|
+
check(1, M.gamma(1, SCALE))
|
483
|
+
check(SQRT_PI.divide(2, SCALE, :down), M.gamma(Decimal("1.5"), SCALE))
|
484
|
+
check(1, M.gamma(2, SCALE))
|
485
|
+
check((3 * SQRT_PI).divide(4, SCALE, :down),
|
486
|
+
M.gamma(Decimal("2.5"), SCALE))
|
487
|
+
check(2, M.gamma(3, SCALE))
|
488
|
+
check((15 * SQRT_PI).divide(8, SCALE, :down),
|
489
|
+
M.gamma(Decimal("3.5"), SCALE))
|
490
|
+
check(6, M.gamma(4, SCALE))
|
491
|
+
|
492
|
+
assert_raise(Errno::EDOM) {M.gamma(-Decimal::INFINITY, SCALE)} # XXX
|
493
|
+
end
|
494
|
+
|
495
|
+
def test_math_lgamma
|
496
|
+
g, s = M.lgamma(Decimal("-1.5"), SCALE)
|
497
|
+
check(M.log((4 * SQRT_PI).divide(3, SCALE, :down), SCALE), g)
|
498
|
+
assert_equal(1, s)
|
499
|
+
|
500
|
+
g, s = M.lgamma(Decimal("-0.5"), SCALE)
|
501
|
+
check(M.log(2 * SQRT_PI, SCALE), g)
|
502
|
+
assert_equal(-1, s)
|
503
|
+
|
504
|
+
g, s = M.lgamma(Decimal("0.5"), SCALE)
|
505
|
+
check(M.log(SQRT_PI, SCALE), g)
|
506
|
+
assert_equal(1, s)
|
507
|
+
|
508
|
+
assert_equal([0, 1], M.lgamma(1, SCALE))
|
509
|
+
|
510
|
+
g, s = M.lgamma(Decimal("1.5"), SCALE)
|
511
|
+
check(M.log(SQRT_PI.divide(2, SCALE, :down), SCALE), g)
|
512
|
+
assert_equal(1, s)
|
513
|
+
|
514
|
+
assert_equal([0, 1], M.lgamma(2, SCALE))
|
515
|
+
|
516
|
+
g, s = M.lgamma(Decimal("2.5"), SCALE)
|
517
|
+
check(M.log((3 * SQRT_PI).divide(4, SCALE, :down), SCALE), g)
|
518
|
+
assert_equal(1, s)
|
519
|
+
|
520
|
+
g, s = M.lgamma(3, SCALE)
|
521
|
+
check(M.log(2, SCALE), g)
|
522
|
+
assert_equal(1, s)
|
523
|
+
|
524
|
+
g, s = M.lgamma(Decimal("3.5"), SCALE)
|
525
|
+
check(M.log((15 * SQRT_PI).divide(8, SCALE, :down), SCALE), g)
|
526
|
+
assert_equal(1, s)
|
527
|
+
|
528
|
+
g, s = M.lgamma(4, SCALE)
|
529
|
+
check(M.log(6, SCALE), g)
|
530
|
+
assert_equal(1, s)
|
531
|
+
|
532
|
+
assert_raise(Errno::EDOM) {M.lgamma(-Decimal::INFINITY, SCALE)} # XXX
|
533
|
+
end
|
534
|
+
|
535
|
+
def test_math_cbrt
|
536
|
+
check(0, M.cbrt(0, SCALE))
|
537
|
+
check(1, M.cbrt(1, SCALE))
|
538
|
+
check(2, M.cbrt(8, SCALE))
|
539
|
+
assert_equal(INFINITY, M.cbrt(INFINITY, SCALE))
|
540
|
+
assert_equal(-INFINITY, M.cbrt(-INFINITY, SCALE))
|
541
|
+
assert_equal("0.0", M.cbrt(Decimal("0.0"), SCALE).to_s[0..2])
|
542
|
+
assert_equal("-0.0", M.cbrt(Decimal("-0.0"), SCALE).to_s[0..3]) # insure it is -0.0, not +0.0
|
543
|
+
check(-1, M.cbrt(-1, SCALE))
|
544
|
+
check(-2, M.cbrt(-8, SCALE))
|
545
|
+
end
|
546
|
+
end
|