long-decimal 0.00.07 → 0.00.08

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/Rakefile CHANGED
@@ -2,7 +2,7 @@
2
2
  # Rakefile for long-decimal project
3
3
  #
4
4
  # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/Rakefile,v 1.1 2006/02/25 19:52:11 bk1 Exp $
5
- # CVS-Label: $Name: PRE_ALPHA_0_06 $
5
+ # CVS-Label: $Name: PRE_ALPHA_0_08 $
6
6
  # Author: $Author: bk1 $ (Karl Brodowsky)
7
7
  #
8
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.00.07
1
+ 0.00.08
data/lib/longdecimal.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  #
2
2
  # longdecimal.rb -- Arbitrary precision decimals with fixed decimal point
3
3
  #
4
- # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/lib/longdecimal.rb,v 1.3 2006/02/28 09:57:10 bk1 Exp $
5
- # CVS-Label: $Name: PRE_ALPHA_0_07 $
4
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/lib/longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $
5
+ # CVS-Label: $Name: PRE_ALPHA_0_08 $
6
6
  # Author: $Author: bk1 $ (Karl Brodowsky)
7
7
  #
8
8
  require "complex"
9
9
  require "rational"
10
- # require "bigdecimal"
10
+ require "bigdecimal"
11
+
11
12
  # require "bigdecimal/math"
12
13
 
13
14
  #
@@ -216,7 +217,7 @@ module LongMath
216
217
  return m1 - m2
217
218
 
218
219
  elsif (x.kind_of? LongDecimal)
219
- m1 = x.numerator.multiplicity_of_factor(prime_number)
220
+ m1 = multiplicity_of_factor(x.numerator, prime_number)
220
221
  if (prime_number == 2 || prime_number == 5) then
221
222
  return m1 - x.scale
222
223
  else
@@ -244,6 +245,47 @@ module LongMath
244
245
  end
245
246
  end
246
247
 
248
+ #
249
+ # method for calculating pi to the given number of digits after the
250
+ # decimal point
251
+ # works fine for 1000 or 2000 digits or so.
252
+ # this method could be optimized more, but if you really want to go
253
+ # for more digits, you will find a specialized and optimized program
254
+ # for this specific purpose.
255
+ # (this is the easter egg ;-) )
256
+ def LongMath.calc_pi(prec, final_mode = LongDecimal::ROUND_HALF_DOWN)
257
+ mode = LongDecimal::ROUND_HALF_DOWN
258
+ iprec = 5*(prec+1)
259
+ sprec = (iprec >> 1) + 1
260
+ dprec = (prec+1) << 1
261
+
262
+ a = LongDecimal(1)
263
+ b = (1 / LongDecimal(2).sqrt(iprec,mode)).round_to_scale(iprec, mode)
264
+ c = LongDecimal(5,1)
265
+ k = 1
266
+ pow_k = 2
267
+
268
+ pi = 0
269
+ last_pi = 0
270
+ last_diff = 1
271
+
272
+ loop do
273
+ a, b = ((a + b) / 2).round_to_scale(sprec, mode), (a * b).round_to_scale(iprec, mode).sqrt(sprec, mode)
274
+ c = (c - pow_k * (a * a - b * b)).round_to_scale(iprec, mode)
275
+ pi = (2 * a * a / c).round_to_scale(sprec, mode)
276
+ diff = (pi - last_pi).round_to_scale(dprec, mode).abs
277
+ if (diff.zero? && last_diff.zero?) then
278
+ break
279
+ end
280
+ last_pi = pi
281
+ last_diff = diff
282
+ k += 1
283
+ pow_k = pow_k << 1
284
+ # puts("k=#{k} pi=#{pi.to_s}\nd=#{diff}\n\n")
285
+ end
286
+ pi.round_to_scale(prec, final_mode)
287
+ end
288
+
247
289
  end
248
290
 
249
291
  #
@@ -286,7 +328,7 @@ end
286
328
  # digits and the other one the position of the decimal point.
287
329
  #
288
330
  class LongDecimal < Numeric
289
- @RCS_ID='-$Id: longdecimal.rb,v 1.3 2006/02/28 09:57:10 bk1 Exp $-'
331
+ @RCS_ID='-$Id: longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $-'
290
332
 
291
333
  include LongDecimalRoundingMode
292
334
 
@@ -407,7 +449,10 @@ class LongDecimal < Numeric
407
449
 
408
450
  else
409
451
  # we assume a string or a floating point number
410
- # floating point number is converted to string, so we only deal with strings
452
+ # floating point number or BigDecimal is converted to string, so
453
+ # we only deal with strings
454
+ # this operation is not so common, so there is no urgent need to
455
+ # optimize it
411
456
  num_str = x.to_s
412
457
  len = num_str.length
413
458
 
@@ -618,6 +663,15 @@ class LongDecimal < Numeric
618
663
  self
619
664
  end
620
665
 
666
+ #
667
+ # convert selt into BigDecimal
668
+ #
669
+ def to_bd
670
+ # this operation is probably not used so heavily, so we can live with a
671
+ # string as an intermediate step.
672
+ BigDecimal(self.to_s)
673
+ end
674
+
621
675
  #
622
676
  # LongDecimals can be seen as a fraction with a power of 10 as
623
677
  # denominator for compatibility with other numeric classes this
@@ -1054,6 +1108,11 @@ class LongDecimal < Numeric
1054
1108
  other = other.round_to_scale(scale, ROUND_HALF_UP)
1055
1109
  end
1056
1110
  return other, self
1111
+ elsif other.kind_of? BigDecimal then
1112
+ s, o = other.coerce(self.to_bd)
1113
+ return o, s
1114
+ elsif (other.kind_of? Float) && size > 8 then
1115
+ return coerce(BigDecimal(other.to_s))
1057
1116
  elsif other.kind_of? Numeric then
1058
1117
  s, o = other.coerce(self.to_f)
1059
1118
  return o, s
@@ -1104,7 +1163,7 @@ end
1104
1163
  #
1105
1164
  class LongDecimalQuot < Numeric
1106
1165
 
1107
- @RCS_ID='-$Id: longdecimal.rb,v 1.3 2006/02/28 09:57:10 bk1 Exp $-'
1166
+ @RCS_ID='-$Id: longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $-'
1108
1167
 
1109
1168
  include LongDecimalRoundingMode
1110
1169
 
@@ -1372,6 +1431,8 @@ class LongDecimalQuot < Numeric
1372
1431
  return LongDecimalQuot(other.to_r, scale), self
1373
1432
  elsif other.kind_of? Float then
1374
1433
  return LongDecimalQuot(other.to_ld.to_r, scale), self
1434
+ elsif other.kind_of? BigDecimal then
1435
+ s, o = other.coerce(self.to_bd)
1375
1436
  elsif other.kind_of? Numeric then
1376
1437
  s, o = other.coerce(self.to_f)
1377
1438
  return o, s
@@ -2,8 +2,8 @@
2
2
  #
3
3
  # testlongdecimal.rb -- runit test for longdecimal.rb
4
4
  #
5
- # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/test/testlongdecimal.rb,v 1.3 2006/02/28 09:57:10 bk1 Exp $
6
- # CVS-Label: $Name: PRE_ALPHA_0_07 $
5
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/test/testlongdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $
6
+ # CVS-Label: $Name: PRE_ALPHA_0_08 $
7
7
  # Author: $Author: bk1 $ (Karl Brodowsky)
8
8
  #
9
9
 
@@ -13,10 +13,16 @@ require "runit/testsuite"
13
13
 
14
14
  load "lib/longdecimal.rb"
15
15
 
16
+ #
17
+ # test class for LongDecimal and LongDecimalQuot
18
+ #
16
19
  class TestLongDecimal_class < RUNIT::TestCase
17
20
 
18
- @RCS_ID='-$Id: testlongdecimal.rb,v 1.3 2006/02/28 09:57:10 bk1 Exp $-'
21
+ @RCS_ID='-$Id: testlongdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $-'
19
22
 
23
+ #
24
+ # helper method for test_sqrtb
25
+ #
20
26
  def check_sqrtb(x, s)
21
27
  y = LongMath.sqrtb(x)
22
28
  z = y * y
@@ -26,7 +32,10 @@ class TestLongDecimal_class < RUNIT::TestCase
26
32
  y
27
33
  end
28
34
 
29
- def _test_sqrtb
35
+ #
36
+ # test method sqrtb for calculating sqrt of short integers
37
+ #
38
+ def test_sqrtb
30
39
  assert_equal(Complex(0,1), LongMath.sqrtb(-1), "sqrt(-1)=i")
31
40
  1024.times do |x|
32
41
  check_sqrtb(x, " loop x=#{x}")
@@ -61,6 +70,9 @@ class TestLongDecimal_class < RUNIT::TestCase
61
70
  end
62
71
  end
63
72
 
73
+ #
74
+ # helper method of test_sqrtw
75
+ #
64
76
  def check_sqrtw(x, s)
65
77
  y = LongMath.sqrtw(x)
66
78
  z = y * y
@@ -70,6 +82,9 @@ class TestLongDecimal_class < RUNIT::TestCase
70
82
  y
71
83
  end
72
84
 
85
+ #
86
+ # test method sqrtb for calculating sqrt of long integers
87
+ #
73
88
  def test_sqrtw
74
89
  assert_equal(Complex(0,1), LongMath.sqrtw(-1), "sqrt(-1)=i")
75
90
  1024.times do |x|
@@ -105,6 +120,9 @@ class TestLongDecimal_class < RUNIT::TestCase
105
120
  end
106
121
  end
107
122
 
123
+ #
124
+ # test gcd_with_high_power
125
+ #
108
126
  def test_gcd_with_high_power
109
127
  n = 224
110
128
  assert_equal(32, LongMath.gcd_with_high_power(n, 2), "2-part of 224 is 32")
@@ -112,6 +130,9 @@ class TestLongDecimal_class < RUNIT::TestCase
112
130
  assert_equal(1, LongMath.gcd_with_high_power(n, 3), "3-part of 224 is 1")
113
131
  end
114
132
 
133
+ #
134
+ # test multiplicity_of_factor for integers
135
+ #
115
136
  def test_multiplicity_of_factor
116
137
  n = 224
117
138
  assert_equal(5, LongMath.multiplicity_of_factor(n, 2), "ny_2(224) is 5")
@@ -119,6 +140,9 @@ class TestLongDecimal_class < RUNIT::TestCase
119
140
  assert_equal(0, LongMath.multiplicity_of_factor(n, 3), "ny_3(224) is 0")
120
141
  end
121
142
 
143
+ #
144
+ # test multiplicity_of_factor for rationals
145
+ #
122
146
  def test_rat_multiplicity_of_factor
123
147
  n = Rational(224, 225)
124
148
  assert_equal(5, LongMath.multiplicity_of_factor(n, 2), "ny_2(n) is 5")
@@ -128,6 +152,10 @@ class TestLongDecimal_class < RUNIT::TestCase
128
152
  assert_equal(0, LongMath.multiplicity_of_factor(n, 11), "ny_11(n) is 0")
129
153
  end
130
154
 
155
+ #
156
+ # test multiplicity_of_factor for rationals with numerator and
157
+ # denominator exceeding Float
158
+ #
131
159
  def test_rat_long_multiplicity_of_factor
132
160
  n = Rational(224*(10**600+1), 225*(5**800))
133
161
  assert_equal(5, LongMath.multiplicity_of_factor(n, 2), "ny_2(n) is 5")
@@ -137,6 +165,22 @@ class TestLongDecimal_class < RUNIT::TestCase
137
165
  assert_equal(0, LongMath.multiplicity_of_factor(n, 11), "ny_11(n) is 0")
138
166
  end
139
167
 
168
+ #
169
+ # test multiplicity_of_factor for LongDecimal
170
+ #
171
+ def test_rat_multiplicity_of_factor
172
+ # 0.729
173
+ n = LongDecimal(729, 3)
174
+ assert_equal(-3, LongMath.multiplicity_of_factor(n, 2), "ny_2(n) is -3")
175
+ assert_equal(6, LongMath.multiplicity_of_factor(n, 3), "ny_3(n) is 6")
176
+ assert_equal(-3, LongMath.multiplicity_of_factor(n, 5), "ny_5(n) is -3")
177
+ assert_equal(0, LongMath.multiplicity_of_factor(n, 7), "ny_7(n) is 0")
178
+ assert_equal(0, LongMath.multiplicity_of_factor(n, 11), "ny_11(n) is 0")
179
+ end
180
+
181
+ #
182
+ # test construction from Integer
183
+ #
140
184
  def test_int_init
141
185
  l = LongDecimal(224)
142
186
  assert_equal(224, l.to_i, "no loss of information for integers allowed")
@@ -148,6 +192,9 @@ class TestLongDecimal_class < RUNIT::TestCase
148
192
  assert_equal(1, l.to_i, "loss of information 1.9->1")
149
193
  end
150
194
 
195
+ #
196
+ # test construction from Rational
197
+ #
151
198
  def test_rat_init
152
199
  r = Rational(227, 100)
153
200
  l = LongDecimal(r)
@@ -159,6 +206,9 @@ class TestLongDecimal_class < RUNIT::TestCase
159
206
  assert((r - l.to_r).to_f.abs < 0.01, "difference of #{r.inspect} and #{l.inspect} must be less 0.01 but is #{(r - l.to_r).to_f.abs}")
160
207
  end
161
208
 
209
+ #
210
+ # test construction from Float
211
+ #
162
212
  def test_float_init
163
213
  s = "5.32"
164
214
  l = LongDecimal(s)
@@ -171,6 +221,24 @@ class TestLongDecimal_class < RUNIT::TestCase
171
221
  assert_equal("0.000271", l.to_s, "l=#{l.inspect} f=#{f.inspect}")
172
222
  end
173
223
 
224
+ #
225
+ # test construction from BigDecimal
226
+ #
227
+ def test_bd_init
228
+ b = BigDecimal("5.32")
229
+ l = LongDecimal(b)
230
+ assert_equal(b, l.to_bd, "l=#{l.inspect}")
231
+ b = BigDecimal("2.24")
232
+ l = LongDecimal(b)
233
+ assert((b.to_f - l.to_f).abs < 1e-9, "l=#{l.inspect} b=#{b.inspect}")
234
+ b = BigDecimal("2.71E-4")
235
+ l = LongDecimal(b)
236
+ assert_equal("0.000271", l.to_s, "l=#{l.inspect} b=#{b.inspect}")
237
+ end
238
+
239
+ #
240
+ # test rounding with ROUND_UP
241
+ #
174
242
  def test_round_to_scale_up
175
243
  l = LongDecimal("2.21")
176
244
  r = l.round_to_scale(1, LongDecimal::ROUND_UP)
@@ -193,6 +261,9 @@ class TestLongDecimal_class < RUNIT::TestCase
193
261
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
194
262
  end
195
263
 
264
+ #
265
+ # test rounding with ROUND_DOWN
266
+ #
196
267
  def test_round_to_scale_down
197
268
  l = LongDecimal("2.29")
198
269
  r = l.round_to_scale(1, LongDecimal::ROUND_DOWN)
@@ -215,6 +286,9 @@ class TestLongDecimal_class < RUNIT::TestCase
215
286
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
216
287
  end
217
288
 
289
+ #
290
+ # test rounding with ROUND_CEILING
291
+ #
218
292
  def test_round_to_scale_ceiling
219
293
  l = LongDecimal("2.21")
220
294
  r = l.round_to_scale(1, LongDecimal::ROUND_CEILING)
@@ -237,6 +311,9 @@ class TestLongDecimal_class < RUNIT::TestCase
237
311
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
238
312
  end
239
313
 
314
+ #
315
+ # test rounding with ROUND_FLOOR
316
+ #
240
317
  def test_round_to_scale_floor
241
318
  l = LongDecimal("2.29")
242
319
  r = l.round_to_scale(1, LongDecimal::ROUND_FLOOR)
@@ -259,6 +336,9 @@ class TestLongDecimal_class < RUNIT::TestCase
259
336
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
260
337
  end
261
338
 
339
+ #
340
+ # test rounding with ROUND_HALF_UP
341
+ #
262
342
  def test_round_to_scale_half_up
263
343
  l = LongDecimal("2.20")
264
344
  r = l.round_to_scale(1, LongDecimal::ROUND_HALF_UP)
@@ -297,6 +377,9 @@ class TestLongDecimal_class < RUNIT::TestCase
297
377
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
298
378
  end
299
379
 
380
+ #
381
+ # test rounding with ROUND_HALF_DOWN
382
+ #
300
383
  def test_round_to_scale_half_down
301
384
  l = LongDecimal("2.20")
302
385
  r = l.round_to_scale(1, LongDecimal::ROUND_HALF_DOWN)
@@ -335,6 +418,9 @@ class TestLongDecimal_class < RUNIT::TestCase
335
418
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
336
419
  end
337
420
 
421
+ #
422
+ # test rounding with ROUND_HALF_EVEN
423
+ #
338
424
  def test_round_to_scale_half_even
339
425
  l = LongDecimal("2.20")
340
426
  r = l.round_to_scale(1, LongDecimal::ROUND_HALF_EVEN)
@@ -381,6 +467,9 @@ class TestLongDecimal_class < RUNIT::TestCase
381
467
  assert_equal("2.2400", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
382
468
  end
383
469
 
470
+ #
471
+ # test rounding with ROUND_UNNECESSARY
472
+ #
384
473
  def test_round_to_scale_unnecessary
385
474
  l = LongDecimal("2.24")
386
475
  r = l.round_to_scale(4, LongDecimal::ROUND_UNNECESSARY)
@@ -397,6 +486,9 @@ class TestLongDecimal_class < RUNIT::TestCase
397
486
  end
398
487
  end
399
488
 
489
+ #
490
+ # test conversion to String
491
+ #
400
492
  def test_to_s
401
493
  l = LongDecimal(224, 0)
402
494
  assert_equal("224", l.to_s, "l=#{l.inspect}")
@@ -421,6 +513,9 @@ class TestLongDecimal_class < RUNIT::TestCase
421
513
  assert_equal("-0.0224", l.to_s, "l=#{l.inspect}")
422
514
  end
423
515
 
516
+ #
517
+ # test conversion to Rational
518
+ #
424
519
  def test_to_r
425
520
  l = LongDecimal(224, 0)
426
521
  assert_equal(l, l.to_r.to_ld, "l=#{l.inspect}")
@@ -434,6 +529,9 @@ class TestLongDecimal_class < RUNIT::TestCase
434
529
  assert_equal(l, l.to_r.to_ld, "l=#{l.inspect}")
435
530
  end
436
531
 
532
+ #
533
+ # test conversion to Float
534
+ #
437
535
  def test_to_f
438
536
  l = LongDecimal(224, 0)
439
537
  assert((l.to_f - 224).abs < 224 * 0.000001, "l=#{l.inspect}")
@@ -447,6 +545,25 @@ class TestLongDecimal_class < RUNIT::TestCase
447
545
  assert((l.to_f - 0.0224).abs < 0.0224 * 0.000001, "l=#{l.inspect}")
448
546
  end
449
547
 
548
+ #
549
+ # test conversion to BigDecimal
550
+ #
551
+ def test_to_bd
552
+ l = LongDecimal(224, 0)
553
+ assert((l.to_bd - 224).abs < 224 * 0.000001, "l=#{l.inspect}")
554
+ l = LongDecimal(224, 1)
555
+ assert((l.to_bd - 22.4).abs < 22.4 * 0.000001, "l=#{l.inspect}")
556
+ l = LongDecimal(224, 2)
557
+ assert((l.to_bd - 2.24).abs < 2.24 * 0.000001, "l=#{l.inspect}")
558
+ l = LongDecimal(224, 3)
559
+ assert((l.to_bd - 0.224).abs < 0.224 * 0.000001, "l=#{l.inspect}")
560
+ l = LongDecimal(224, 4)
561
+ assert((l.to_bd - 0.0224).abs < 0.0224 * 0.000001, "l=#{l.inspect}")
562
+ end
563
+
564
+ #
565
+ # test conversion to Integer
566
+ #
450
567
  def test_to_i
451
568
  l = LongDecimal(224, 0)
452
569
  assert_equal(224, l.to_i, "l=#{l.inspect}")
data/version.rb CHANGED
@@ -3,8 +3,8 @@
3
3
  #
4
4
  # version.rb -- extract version information from files
5
5
  #
6
- # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/version.rb,v 1.3 2006/02/25 20:05:53 bk1 Exp $
7
- # CVS-Label: $Name: PRE_ALPHA_0_06 $
6
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/version.rb,v 1.4 2006/03/02 20:33:55 bk1 Exp $
7
+ # CVS-Label: $Name: PRE_ALPHA_0_08 $
8
8
  # Author: $Author: bk1 $ (Karl Brodowsky)
9
9
  #
10
10
 
@@ -24,7 +24,7 @@ ARGV.each do |file|
24
24
 
25
25
  str = ""
26
26
  if name =~ /PRE_ALPHA_(\d+)_(\d+)/ then
27
- str = sprintf("0.%02d.%02d", $1, $2)
27
+ str = sprintf("0.%02d.%02d", $1.to_i, $2.to_i)
28
28
  else
29
29
  str = version
30
30
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: long-decimal
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.00.07
7
- date: 2006-02-28 00:00:00 +01:00
6
+ version: 0.00.08
7
+ date: 2006-03-02 00:00:00 +01:00
8
8
  summary: LongDecimal for numbers with fixed point
9
9
  require_paths:
10
10
  - lib