long-decimal 0.00.21 → 0.00.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. data/README +23 -16
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/doc/classes/LongDecimal.html +343 -343
  5. data/doc/classes/LongDecimal.src/M000036.html +4 -4
  6. data/doc/classes/LongDecimal.src/M000037.html +4 -4
  7. data/doc/classes/LongDecimal.src/M000038.html +4 -4
  8. data/doc/classes/LongDecimal.src/M000039.html +4 -4
  9. data/doc/classes/LongDecimal.src/M000040.html +4 -6
  10. data/doc/classes/LongDecimal.src/M000041.html +4 -106
  11. data/doc/classes/LongDecimal.src/M000042.html +6 -21
  12. data/doc/classes/LongDecimal.src/M000043.html +105 -10
  13. data/doc/classes/LongDecimal.src/M000044.html +17 -23
  14. data/doc/classes/LongDecimal.src/M000045.html +10 -18
  15. data/doc/classes/LongDecimal.src/M000046.html +27 -4
  16. data/doc/classes/LongDecimal.src/M000047.html +17 -13
  17. data/doc/classes/LongDecimal.src/M000048.html +4 -28
  18. data/doc/classes/LongDecimal.src/M000049.html +15 -4
  19. data/doc/classes/LongDecimal.src/M000050.html +26 -6
  20. data/doc/classes/LongDecimal.src/M000051.html +4 -6
  21. data/doc/classes/LongDecimal.src/M000052.html +8 -4
  22. data/doc/classes/LongDecimal.src/M000053.html +6 -15
  23. data/doc/classes/LongDecimal.src/M000054.html +4 -7
  24. data/doc/classes/LongDecimal.src/M000055.html +15 -4
  25. data/doc/classes/LongDecimal.src/M000056.html +6 -14
  26. data/doc/classes/LongDecimal.src/M000057.html +4 -13
  27. data/doc/classes/LongDecimal.src/M000058.html +15 -4
  28. data/doc/classes/LongDecimal.src/M000059.html +13 -4
  29. data/doc/classes/LongDecimal.src/M000060.html +4 -4
  30. data/doc/classes/LongDecimal.src/M000062.html +4 -5
  31. data/doc/classes/LongDecimal.src/M000063.html +5 -4
  32. data/doc/classes/LongDecimal.src/M000064.html +5 -8
  33. data/doc/classes/LongDecimal.src/M000065.html +4 -9
  34. data/doc/classes/LongDecimal.src/M000066.html +6 -7
  35. data/doc/classes/LongDecimal.src/M000067.html +6 -6
  36. data/doc/classes/LongDecimal.src/M000068.html +9 -4
  37. data/doc/classes/LongDecimal.src/M000069.html +7 -13
  38. data/doc/classes/LongDecimal.src/M000070.html +4 -9
  39. data/doc/classes/LongDecimal.src/M000071.html +13 -7
  40. data/doc/classes/LongDecimal.src/M000072.html +7 -18
  41. data/doc/classes/LongDecimal.src/M000073.html +8 -7
  42. data/doc/classes/LongDecimal.src/M000074.html +20 -5
  43. data/doc/classes/LongDecimal.src/M000075.html +7 -8
  44. data/doc/classes/LongDecimal.src/M000076.html +5 -9
  45. data/doc/classes/LongDecimal.src/M000077.html +5 -5
  46. data/doc/classes/LongDecimal.src/M000078.html +9 -4
  47. data/doc/classes/LongDecimal.src/M000079.html +8 -6
  48. data/doc/classes/LongDecimal.src/M000080.html +4 -7
  49. data/doc/classes/LongDecimal.src/M000081.html +7 -4
  50. data/doc/classes/LongDecimal.src/M000082.html +7 -4
  51. data/doc/classes/LongDecimal.src/M000083.html +4 -9
  52. data/doc/classes/LongDecimal.src/M000084.html +4 -9
  53. data/doc/classes/LongDecimal.src/M000085.html +9 -5
  54. data/doc/classes/LongDecimal.src/M000086.html +7 -7
  55. data/doc/classes/LongDecimal.src/M000087.html +5 -4
  56. data/doc/classes/LongDecimal.src/M000088.html +9 -4
  57. data/doc/classes/LongDecimal.src/M000089.html +4 -4
  58. data/doc/classes/LongDecimal.src/M000090.html +4 -4
  59. data/doc/classes/LongDecimal.src/M000091.html +4 -59
  60. data/doc/classes/LongDecimal.src/M000092.html +4 -4
  61. data/doc/classes/LongDecimal.src/M000093.html +59 -4
  62. data/doc/classes/LongDecimal.src/M000094.html +4 -5
  63. data/doc/classes/LongDecimal.src/M000095.html +4 -4
  64. data/doc/classes/LongDecimal.src/M000098.html +5 -4
  65. data/doc/classes/LongDecimal.src/M000099.html +5 -4
  66. data/doc/classes/LongDecimal.src/M000100.html +4 -4
  67. data/doc/classes/LongDecimal.src/M000101.html +4 -4
  68. data/doc/classes/LongDecimalBase.html +53 -53
  69. data/doc/classes/LongDecimalBase.src/M000107.html +4 -4
  70. data/doc/classes/LongDecimalBase.src/M000108.html +4 -4
  71. data/doc/classes/LongDecimalBase.src/M000109.html +4 -4
  72. data/doc/classes/LongDecimalBase.src/M000110.html +4 -4
  73. data/doc/classes/LongDecimalBase.src/M000111.html +4 -5
  74. data/doc/classes/LongDecimalBase.src/M000112.html +9 -9
  75. data/doc/classes/LongDecimalBase.src/M000115.html +23 -0
  76. data/doc/classes/LongDecimalQuot.html +174 -133
  77. data/doc/classes/LongDecimalQuot.src/M000003.html +1 -1
  78. data/doc/classes/LongDecimalQuot.src/M000004.html +2 -1
  79. data/doc/classes/LongDecimalQuot.src/M000005.html +1 -1
  80. data/doc/classes/LongDecimalQuot.src/M000006.html +1 -1
  81. data/doc/classes/LongDecimalQuot.src/M000007.html +6 -5
  82. data/doc/classes/LongDecimalQuot.src/M000008.html +5 -4
  83. data/doc/classes/LongDecimalQuot.src/M000009.html +4 -4
  84. data/doc/classes/LongDecimalQuot.src/M000010.html +4 -4
  85. data/doc/classes/LongDecimalQuot.src/M000011.html +4 -4
  86. data/doc/classes/LongDecimalQuot.src/M000012.html +4 -4
  87. data/doc/classes/LongDecimalQuot.src/M000013.html +7 -4
  88. data/doc/classes/LongDecimalQuot.src/M000014.html +5 -8
  89. data/doc/classes/LongDecimalQuot.src/M000015.html +5 -9
  90. data/doc/classes/LongDecimalQuot.src/M000016.html +6 -7
  91. data/doc/classes/LongDecimalQuot.src/M000017.html +4 -4
  92. data/doc/classes/LongDecimalQuot.src/M000018.html +4 -4
  93. data/doc/classes/LongDecimalQuot.src/M000019.html +6 -18
  94. data/doc/classes/LongDecimalQuot.src/M000020.html +8 -7
  95. data/doc/classes/LongDecimalQuot.src/M000021.html +21 -5
  96. data/doc/classes/LongDecimalQuot.src/M000022.html +8 -4
  97. data/doc/classes/LongDecimalQuot.src/M000023.html +5 -96
  98. data/doc/classes/LongDecimalQuot.src/M000024.html +4 -38
  99. data/doc/classes/LongDecimalQuot.src/M000025.html +96 -4
  100. data/doc/classes/LongDecimalQuot.src/M000026.html +38 -4
  101. data/doc/classes/LongDecimalQuot.src/M000027.html +4 -4
  102. data/doc/classes/LongDecimalQuot.src/M000028.html +4 -4
  103. data/doc/classes/LongDecimalQuot.src/M000029.html +4 -4
  104. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.html +10 -10
  105. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000148.html +22 -0
  106. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000149.html +18 -0
  107. data/doc/classes/LongMath.html +159 -161
  108. data/doc/classes/LongMath.src/M000118.html +5 -4
  109. data/doc/classes/LongMath.src/M000119.html +4 -5
  110. data/doc/classes/LongMath.src/M000120.html +4 -4
  111. data/doc/classes/LongMath.src/M000121.html +5 -18
  112. data/doc/classes/LongMath.src/M000122.html +4 -18
  113. data/doc/classes/LongMath.src/M000123.html +18 -5
  114. data/doc/classes/LongMath.src/M000124.html +16 -27
  115. data/doc/classes/LongMath.src/M000125.html +4 -4
  116. data/doc/classes/LongMath.src/M000126.html +17 -45
  117. data/doc/classes/LongMath.src/M000127.html +5 -21
  118. data/doc/classes/LongMath.src/M000128.html +50 -29
  119. data/doc/classes/LongMath.src/M000129.html +21 -6
  120. data/doc/classes/LongMath.src/M000130.html +31 -28
  121. data/doc/classes/LongMath.src/M000131.html +6 -48
  122. data/doc/classes/LongMath.src/M000132.html +33 -8
  123. data/doc/classes/LongMath.src/M000133.html +51 -4
  124. data/doc/classes/LongMath.src/M000134.html +7 -4
  125. data/doc/classes/LongMath.src/M000135.html +4 -64
  126. data/doc/classes/LongMath.src/M000136.html +4 -43
  127. data/doc/classes/LongMath.src/M000137.html +64 -4
  128. data/doc/classes/LongMath.src/M000138.html +43 -4
  129. data/doc/classes/LongMath.src/M000139.html +4 -7
  130. data/doc/classes/LongMath.src/M000140.html +4 -20
  131. data/doc/classes/LongMath.src/M000141.html +4 -18
  132. data/doc/classes/LongMath.src/M000142.html +11 -34
  133. data/doc/classes/LongMath.src/M000143.html +13 -253
  134. data/doc/classes/LongMath.src/M000144.html +40 -16
  135. data/doc/classes/LongMath.src/M000145.html +227 -0
  136. data/doc/classes/LongMath.src/M000146.html +33 -0
  137. data/doc/classes/LongMath/CacheKey.html +6 -6
  138. data/doc/classes/LongMath/CacheKey.src/M000147.html +36 -0
  139. data/doc/classes/Numeric.html +10 -10
  140. data/doc/classes/Numeric.src/M000103.html +18 -0
  141. data/doc/classes/Rational.html +5 -5
  142. data/doc/classes/Rational.src/M000104.html +23 -0
  143. data/doc/created.rid +1 -1
  144. data/doc/files/lib/long-decimal_rb.src/M000001.html +1 -1
  145. data/doc/files/lib/long-decimal_rb.src/M000002.html +1 -1
  146. data/doc/fr_method_index.html +145 -143
  147. data/lib/long-decimal.rb +52 -71
  148. data/test/testlongdecimal.rb +218 -449
  149. data/test/testlongdeclib.rb +485 -0
  150. data/test/testrandom.rb +75 -0
  151. data/version.rb +1 -1
  152. metadata +12 -3
  153. data/doc/files/lib/long-decimal_rb.html +0 -189
@@ -0,0 +1,485 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # library for testlongdecimal.rb
4
+ #
5
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/test/testlongdeclib.rb,v 1.2 2006/04/07 22:26:08 bk1 Exp $
6
+ # CVS-Label: $Name: PRE_ALPHA_0_22 $
7
+ # Author: $Author: bk1 $ (Karl Brodowsky)
8
+ #
9
+
10
+ load "lib/long-decimal.rb"
11
+
12
+ #
13
+ # test class for LongDecimal and LongDecimalQuot
14
+ #
15
+ module TestLongDecHelper
16
+
17
+ @RCS_ID='-$Id: testlongdeclib.rb,v 1.2 2006/04/07 22:26:08 bk1 Exp $-'
18
+
19
+
20
+ #
21
+ # convenience method for comparing two numbers. true if and only if
22
+ # they express the same value
23
+ #
24
+ def assert_val_equal(expected, actual, message="")
25
+ _wrap_assertion {
26
+ full_message = build_message(message, "Expected <?> to match <?>", actual, expected)
27
+ assert_block(full_message) {
28
+ (expected <=> actual).zero?
29
+ }
30
+ }
31
+ end
32
+
33
+ #
34
+ # convenience method for comparing Float with LongDecimal
35
+ # using a delta coming from these
36
+ #
37
+ def assert_mixed_equal(expected_f, actual_ld, message="")
38
+ delta = [ actual_ld.unit, expected_f.abs / 1e10 ].max
39
+ assert_equal_float(expected_f, actual_ld, delta, message)
40
+ end
41
+
42
+ #
43
+ # helper method for test_split_merge_words
44
+ #
45
+ def check_split_merge_words(x, l, wl)
46
+ w = LongMath.split_to_words(x, l)
47
+ y = LongMath.merge_from_words(w, l)
48
+ assert_equal(x, y, "#{x} splitted and merged should be equal but is #{y} l=#{l}")
49
+ assert_equal(wl, w.length, "#{x} splitted to l=#{l} should have length #{wl} but has #{w.length}")
50
+ w
51
+ end
52
+
53
+ #
54
+ # helper method for test_exp
55
+ # tests if exp(x) with precision prec is calculated correctly
56
+ #
57
+ def check_exp_floated(x, prec)
58
+
59
+ print "."
60
+ $stdout.flush
61
+
62
+ # make sure x is LongDecimal
63
+ x0 = x
64
+ x = x.to_ld
65
+ # calculate y = exp(x)
66
+ # eprec = prec+1
67
+ y = LongMath.exp(x, prec)
68
+
69
+ # compare y against z = exp(x) calculated using regular floating point arithmetic
70
+ z = Math.exp(x.to_f)
71
+ yf = y.to_f
72
+ assert((yf - z).abs <= [ y.unit, z.abs / 1e9 ].max, "y=#{yf.to_s} and z=#{z.to_s} should be almost equal x=#{x}")
73
+
74
+ # check by taking log(exp(x))
75
+ # we have to take into account that we might not have enough
76
+ # significant digits, so we have to go down with the precision
77
+ if (y > 0) then
78
+ lprec = prec - 1
79
+ if (y < 1) then
80
+ l10 = (Math.log(y.to_f) / Math.log(10)).round
81
+ lprec += l10
82
+ end
83
+ df = 1
84
+ if (lprec < 0)
85
+ df += lprec.abs
86
+ lprec = 0
87
+ end
88
+ z = LongMath.log(y, lprec)
89
+ delta = z.unit * df
90
+ assert((x - z).abs <= delta, "x=#{x.to_s} and z=#{z.to_s} should be almost equal (#{(x-z).abs.inspect} < d=#{delta.inspect} y=#{y.to_s} lprec=#{lprec} prec=#{prec})")
91
+ end
92
+
93
+ # check by doing calculation with different internal rounding modes. They should not differ.
94
+ yd = LongMath.exp_internal(x, prec, nil, nil, nil, nil, LongDecimal::ROUND_DOWN)
95
+ yu = LongMath.exp_internal(x, prec, nil, nil, nil, nil, LongDecimal::ROUND_UP)
96
+ assert_equal(yd, yu, "the result yd/yu should not depend on the internal rounding mode x0=#{x0} x=#{x} p=#{prec} d=#{(yd-yu).to_f.to_s}")
97
+ assert_equal(y, yu, "the result y/yu should not depend on the internal rounding mode x0=#{x0} x=#{x} p=#{prec} d=#{(y -yu).to_f.to_s}")
98
+ end
99
+
100
+ #
101
+ # helper method for test_exp_int
102
+ # tests if exp(x) with precision prec is calculated correctly
103
+ #
104
+ def check_exp_int(x)
105
+
106
+ # make sure x is LongDecimal
107
+ x0 = x
108
+ x = x.to_ld
109
+ y = LongMath.exp(x, 0)
110
+ assert_equal(y.scale, 0, "scale must be 0")
111
+
112
+ # compare y against z = exp(x) calculated using regular floating point arithmetic
113
+ z = Math.exp(x0.to_f)
114
+ yf = y.to_f
115
+ yi = yf.round
116
+ zi = z.round
117
+ assert((yi-zi).abs / [yf.abs, z.abs, Float::MIN].max < 1e-9, "yi=#{yi} and zi=#{zi} should be equal x=#{x} y=#{y} z=#{z}")
118
+
119
+ if (y > 1)
120
+ w = LongMath.log(y, 0)
121
+ assert((w-x).abs < 1, "log(y)=#{w} must be almost x=#{x0}")
122
+ end
123
+
124
+ end
125
+
126
+ #
127
+ # helper method for test_lm_power_xint
128
+ # tests if exp(x) with precision prec is calculated correctly
129
+ #
130
+ def check_power_xint(x, y, prec)
131
+
132
+ xi = x.to_i
133
+ x = x.to_ld()
134
+ y = y.to_ld()
135
+ z = LongMath.power(x, y, prec)
136
+ zz = LongMath.power_internal(x, y, prec)
137
+ assert((zz - z).abs <= z.unit, "power with and without optimizations z=#{z} zz=#{zz} x=#{x} y=#{y}")
138
+ # compare y against z = exp(x) calculated using regular floating point arithmetic
139
+ zz = (xi) ** (y.to_f)
140
+ zf = z.to_f
141
+ assert((zf - zz).abs < [z.unit.to_f, zz.abs / 1e9 ].max, "z=#{z} and zz=#{zz} should be almost equal x=#{x} y=#{y} (zf=#{zf})")
142
+ end
143
+
144
+ #
145
+ # helper method for test_lm_power_yint
146
+ # tests if exp(x) with precision prec is calculated correctly
147
+ #
148
+ def check_power_yint(x, y, prec)
149
+
150
+ yi = y.to_i
151
+ x = x.to_ld
152
+ y = y.to_ld
153
+
154
+ z = LongMath.power(x, y, prec, LongMath::ROUND_HALF_UP)
155
+ zz = (x ** yi).round_to_scale(prec, LongMath::ROUND_HALF_UP)
156
+ assert_equal(z, zz, "power with ** or power-method x=#{x} y=#{y} z=#{z} zz=#{zz}")
157
+ zz = LongMath.power_internal(x, y, prec)
158
+ assert((zz - z).abs <= z.unit, "power with and without optimizations x=#{x} y=#{y} z=#{z} zz=#{zz}")
159
+
160
+ zz = (x.to_f) ** (y.to_f)
161
+ zf = z.to_f
162
+ # assert((zf - zz).abs / [zf.abs, zz.abs, Float::MIN].max < 1e-9, "z=#{zf.to_s} and zz=#{zz.to_s} should be almost equal x=#{x} y=#{y} z=#{z} zz=#{zz}")
163
+ assert((zf - zz).abs < [ z.unit.to_f, zf.abs / 1e9 ].max, "zf=#{zf.to_s} and zz=#{zz.to_s} should be almost equal x=#{x} y=#{y} z=#{z} zz=#{zz}")
164
+ end
165
+
166
+ #
167
+ # helper method for test_log
168
+ # tests if log(x) with precision prec is calculated correctly
169
+ #
170
+ def check_log_floated(x, prec, divisor=1e9, summand=0)
171
+
172
+ print ","
173
+ $stdout.flush
174
+
175
+ # make sure x is LongDecimal
176
+ x0 = x
177
+ x = x.to_ld
178
+ # calculate y = log(x)
179
+ y = LongMath.log(x, prec)
180
+
181
+ # compare y against z = exp(x) calculated using regular floating
182
+ # point arithmetic
183
+ if (x <= LongMath::MAX_FLOATABLE) then
184
+ xf = x.to_f
185
+ if (xf > 0) then
186
+ z = Math.log(x.to_f)
187
+ zl = z.to_ld(y.scale)
188
+ delta = [ y.unit, z.abs / divisor + summand ].max
189
+ assert((y - zl).abs <= delta, "y=#{y.to_s} (#{y.to_f}) and z=#{z.to_s} (#{zl.to_f}) should be almost equal (d=#{delta.inspect} x=#{x} y=#{y})")
190
+ end
191
+ end
192
+
193
+ # check by taking exp(log(y))
194
+ # we have to take into account that we might not have enough
195
+ # significant digits, so we have to go down with the precision
196
+ if (y <= LongMath::MAX_EXP_ABLE) then
197
+ eprec = prec - 1
198
+ if (y > 1) then
199
+ ly = 0
200
+ if (y > LongMath::MAX_FLOATABLE) then
201
+ puts("unusual y=#{y} y=#{y}\n")
202
+ ly = LongMath::MAX_EXP_ABLE
203
+ else
204
+ ly = Math.log(y.to_f)
205
+ end
206
+ # l10 = (ly * (1.2+2/(prec+1.0)) / Math.log(10)).ceil
207
+ l10 = (y.to_f * (1.2+2/(prec+1.0)) / Math.log(10)).ceil
208
+ # l10 = (y.to_f / Math.log(10)).ceil
209
+ eprec -= l10
210
+ end
211
+ df = 1
212
+ if (eprec < 0)
213
+ df += eprec.abs
214
+ eprec = 0
215
+ end
216
+ z = LongMath.exp(y, eprec)
217
+ u = z.unit
218
+ delta = (u + u.move_point_left(1)) * df
219
+ assert((x - z).abs <= delta, "x=#{x.to_s} and z=#{z.to_s} should be almost equal (#{(x-z).abs.inspect} < d=#{delta.inspect} y=#{y.to_s} eprec=#{eprec} prec=#{prec})")
220
+ end
221
+
222
+ # check by doing calculation with different internal rounding modes. They should not differ.
223
+ yd = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_DOWN)
224
+ yu = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_UP)
225
+ assert_equal(yd, yu, "the result yd/yu should not depend on the internal rounding mode yd=#{yd} yu=#{yu} y=#{y} p=#{prec} d=#{(yd-yu).to_f.to_s}")
226
+ assert_equal(y, yu, "the result y/yu should not depend on the internal rounding mode yd=#{yd} yu=#{yu} y=#{y} p=#{prec} d=#{(y -yu).to_f.to_s}")
227
+ end
228
+
229
+ #
230
+ # helper method for test_lm_power
231
+ # tests if LongMath::power(x, y, prec) with precision prec is calculated correctly
232
+ #
233
+ def check_power_floated(x, y, prec)
234
+
235
+ # puts("start: check_power_floated: x=#{x} y=#{y} prec=#{prec}\n")
236
+ # make sure x and y are LongDecimal
237
+ x0 = x
238
+ x = x.to_ld
239
+ y0 = y
240
+ y = y.to_ld
241
+ # calculate z = x**y
242
+ z = LongMath.power(x, y, prec)
243
+
244
+ # compare y against w = x**y calculated using regular floating point arithmetic
245
+ w = (x.to_f) ** (y.to_f)
246
+ zf = z.to_f
247
+ # assert((zf - w).abs / [zf.abs, w.abs, Float::MIN].max < 1e-9, "z=#{zf.to_s} and w=#{w.to_s} should be almost equal x=#{x} y=#{y}")
248
+ assert((zf - w).abs <= [ z.unit, zf.abs / 1e9 ].max, "z=#{zf.to_s} and w=#{w.to_s} should be almost equal x=#{x} y=#{y}")
249
+
250
+ # check by taking log(z) = y * log(x)
251
+ # we have to take into account that we might not have enough
252
+ # significant digits, so we have to go down with the precision
253
+ if (z > 0) then
254
+ lprec = prec
255
+ if (z < 1) then
256
+ l10 = (Math.log(z.to_f) / Math.log(10)).floor
257
+ lprec += l10
258
+ end
259
+ if (x < 1) then
260
+ l10 = (Math.log(x.to_f) / Math.log(10)).floor
261
+ lprec += l10
262
+ end
263
+ unit = (10**(-lprec)).to_ld
264
+ if (lprec < 0)
265
+ lprec = 0
266
+ end
267
+ l10y = 0
268
+ if (y > 1) then
269
+ l10y = (Math.log(y.to_f) / Math.log(10)).ceil
270
+ end
271
+ u = LongMath.log(z, lprec)
272
+ v = LongMath.log(x, lprec+l10y)
273
+ yv = (y*v).round_to_scale(lprec, LongDecimal::ROUND_HALF_DOWN)
274
+ assert((u - yv).abs <= unit, "u=#{u} and yv=y*v=#{yv} should be almost equal (unit=#{unit} x=#{x.to_s} y=#{y.to_s} z=#{z.to_s} u=#{u.to_s} v=#{v.to_s} lprec=#{lprec} prec=#{prec})")
275
+ end
276
+ # puts("ok check_power_floated: x=#{x} y=#{y} prec=#{prec}\n")
277
+
278
+ end
279
+
280
+ #
281
+ # helper method for test_log10
282
+ # tests if log10(x) with precision prec is calculated correctly
283
+ #
284
+ def check_log10_floated(x, prec)
285
+
286
+ # make sure x is LongDecimal
287
+ x0 = x
288
+ x = x.to_ld
289
+ # calculate y = log10(x)
290
+ y = LongMath.log10(x, prec)
291
+
292
+ # compare y against z = log10(x) calculated using regular floating
293
+ # point arithmetic
294
+ if (x <= LongMath::MAX_FLOATABLE) then
295
+ xf = x.to_f
296
+ if (xf > 0) then
297
+ z = Math.log(x.to_f) / Math.log(10)
298
+ yf = y.to_f
299
+ assert((yf - z).abs / [yf.abs, z.abs, Float::MIN].max < 1e-9, "y=#{yf.to_s} and z=#{z.to_s} should be almost equal x=#{x}")
300
+ end
301
+ end
302
+
303
+ # check by taking 10**(log10(x))
304
+ # we have to take into account that we might not have enough
305
+ # significant digits, so we have to go down with the precision
306
+ if (y <= LongMath::MAX_EXP_ABLE) then
307
+ eprec = prec
308
+ if (y > 1) then
309
+ lx = 0
310
+ if (x > LongMath::MAX_FLOATABLE) then
311
+ puts("unusual x=#{x} y=#{y}\n")
312
+ lx = LongMath::MAX_EXP_ABLE
313
+ else
314
+ lx = Math.log(x.to_f)
315
+ end
316
+ l10 = (lx / Math.log(10)).ceil
317
+ eprec = [ eprec - l10, 0 ].max
318
+ end
319
+
320
+ z = LongMath.power(10.to_ld, y, eprec)
321
+ # zz = LongMath.exp10(y, eprec)
322
+ # assert((zz - z).abs <= z.unit, "zz=#{zz.to_s} and z=#{z.to_s} should be almost equal (y=#{y.to_s} eprec=#{eprec} prec=#{prec})")
323
+ assert((x - z).abs <= z.unit, "x=#{x.to_s} and z=#{z.to_s} should be almost equal (y=#{y.to_s} eprec=#{eprec} prec=#{prec})")
324
+ end
325
+
326
+ end
327
+
328
+ #
329
+ # helper method for test_log10
330
+ # tests if log10(x) with precision prec is calculated correctly
331
+ #
332
+ def check_log10_exact(x, log10x, prec)
333
+
334
+ # make sure x is LongDecimal
335
+ x0 = x
336
+ x = x.to_ld
337
+ log10x = log10x.to_ld(prec)
338
+ # calculate y = log10(x)
339
+ y = LongMath.log10(x, prec)
340
+ assert_equal(y, log10x, "log x should match exactly x=#{x} y=#{y} log10x=#{log10x}")
341
+ end
342
+
343
+ #
344
+ # helper method for test_log2
345
+ # tests if log2(x) with precision prec is calculated correctly
346
+ #
347
+ def check_log2_floated(x, prec)
348
+
349
+ # make sure x is LongDecimal
350
+ x0 = x
351
+ x = x.to_ld
352
+ # calculate y = log2(x)
353
+ y = LongMath.log2(x, prec)
354
+
355
+ # compare y against z = log2(x) calculated using regular floating
356
+ # point arithmetic
357
+ if (x <= LongMath::MAX_FLOATABLE) then
358
+ xf = x.to_f
359
+ if (xf > 0) then
360
+ z = Math.log(x.to_f) / Math.log(2)
361
+ yf = y.to_f
362
+ assert((yf - z).abs / [yf.abs, z.abs, Float::MIN].max < 1e-9, "y=#{yf.to_s} and z=#{z.to_s} should be almost equal x=#{x}")
363
+ end
364
+ end
365
+
366
+ # check by taking 2**(log2(x))
367
+ # we have to take into account that we might not have enough
368
+ # significant digits, so we have to go down with the precision
369
+ if (y <= LongMath::MAX_EXP_ABLE) then
370
+ eprec = prec
371
+ if (y > 1) then
372
+ lx = 0
373
+ if (x > LongMath::MAX_FLOATABLE) then
374
+ puts("unusual x=#{x} y=#{y}\n")
375
+ lx = LongMath::MAX_EXP_ABLE
376
+ else
377
+ lx = Math.log(x.to_f)
378
+ end
379
+ l10 = (lx / Math.log(10)).ceil
380
+ eprec = [ eprec - l10, 0 ].max
381
+ end
382
+
383
+ z = LongMath.power(2.to_ld, y, eprec)
384
+ # zz = LongMath.exp2(y, eprec)
385
+ # assert((zz - z).abs <= z.unit, "zz=#{zz.to_s} and z=#{z.to_s} should be almost equal (y=#{y.to_s} eprec=#{eprec} prec=#{prec})")
386
+ assert((x - z).abs <= z.unit, "x=#{x.to_s} and z=#{z.to_s} should be almost equal (y=#{y.to_s} eprec=#{eprec} prec=#{prec})")
387
+ end
388
+
389
+ end
390
+
391
+ #
392
+ # helper method for test_log2
393
+ # tests if log2(x) with precision prec is calculated correctly
394
+ #
395
+ def check_log2_exact(x, log2x, prec)
396
+
397
+ # make sure x is LongDecimal
398
+ x0 = x
399
+ x = x.to_ld
400
+ log2x = log2x.to_ld(prec)
401
+ # calculate y = log2(x)
402
+ y = LongMath.log2(x, prec)
403
+ assert_equal(y, log2x, "log x should match exactly x=#{x} y=#{y} log2x=#{log2x} prec=#{prec}")
404
+ end
405
+
406
+ #
407
+ # helper method for test_int_sqrtb
408
+ #
409
+ def check_sqrtb(x, s)
410
+ y = LongMath.sqrtb(x)
411
+ z = y * y
412
+ zz = (y+1)*(y+1)
413
+ assert(0 <= y, "sqrt must be >= 0" + s)
414
+ assert(z <= x && x < zz, "y=#{y}=sqrt(#{x}) and x in [#{z}, #{zz})" + s)
415
+ y
416
+ end
417
+
418
+ #
419
+ # helper method of test_int_sqrtw
420
+ #
421
+ def check_sqrtw(x, s)
422
+ y = LongMath.sqrtw(x)
423
+ z = y * y
424
+ zz = (y+1)*(y+1)
425
+ assert(0 <= y, "sqrt must be >= 0" + s)
426
+ assert(z <= x && x < zz, "y=#{y}=sqrt(#{x}) and x in [#{z}, #{zz})" + s)
427
+ y
428
+ end
429
+
430
+ #
431
+ # helper method for test_int_sqrtb_with_remainder
432
+ #
433
+ def check_sqrtb_with_remainder(x, s)
434
+ y, r = LongMath.sqrtb_with_remainder(x)
435
+ z0 = y * y
436
+ z1 = z0 + r
437
+ z2 = (y+1)*(y+1)
438
+ assert(0 <= y, "sqrt _with_remaindermust be >= 0" + s)
439
+ assert_equal(z1, x, "x=#{x} y=#{y} r=#{r} z0=#{z0} z1=#{z1} z2=#{z2}" + s)
440
+ assert(z0 <= x && x < z2, "y=#{y}=sqrt(_with_remainder#{x}) and x in [#{z0}, #{z2}) r=#{r} z0=#{z0} z1=#{z1} z2=#{z2}" + s)
441
+ y
442
+ end
443
+
444
+ #
445
+ # helper method for test_int_sqrtw_with_remainder
446
+ #
447
+ def check_sqrtw_with_remainder(x, s)
448
+ y, r = LongMath.sqrtw_with_remainder(x)
449
+ z0 = y * y
450
+ z1 = z0 + r
451
+ z2 = (y+1)*(y+1)
452
+ assert(0 <= y, "sqrt _with_remaindermust be >= 0" + s)
453
+ assert_equal(z1, x, "x=#{x} y=#{y} r=#{r} z0=#{z0} z1=#{z1} z2=#{z2}" + s)
454
+ assert(z0 <= x && x < z2, "y=#{y}=sqrt(_with_remainder#{x}) and x in [#{z0}, #{z2}) r=#{r} z0=#{z0} z1=#{z1} z2=#{z2}" + s)
455
+ y
456
+ end
457
+
458
+ #
459
+ # helper method of test_sqrt
460
+ #
461
+ def check_sqrt(x, scale, mode, su0, su1, str)
462
+ y = x.sqrt(scale, mode)
463
+ z0 = (y+su0*y.unit).square
464
+ z1 = (y+su1*y.unit).square
465
+ assert(0 <= y.sign, "sqrt must be >= 0" + str)
466
+ assert(z0 <= x && x <= z1, "y=#{y}=sqrt(#{x}) and x in [#{z0}, #{z1}) " + str)
467
+ y
468
+ end
469
+
470
+ #
471
+ # helper method of test_sqrt_with_remainder
472
+ #
473
+ def check_sqrt_with_remainder(x, scale, str)
474
+ y, r = x.sqrt_with_remainder(scale)
475
+ z0 = y.square
476
+ z1 = y.succ.square
477
+ assert(0 <= y.sign, "sqrt must be >= 0" + str)
478
+ assert(z0 <= x && x < z1, "y=#{y}=sqrt(#{x}) and x in [#{z0}, #{z1}) " + str)
479
+ assert((x - z0 - r).zero?, "x=y*y+r x=#{x} z0=#{z0} z1=#{z1} r=#{r} total=#{x - z0 - r} " + str)
480
+ r
481
+ end
482
+
483
+ end
484
+
485
+ # end of file testlongdecimal.rb