long-decimal 1.00.02 → 1.00.03

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module LongDecimalSupport
2
- VERSION = "1.00.02"
2
+ VERSION = "1.00.03"
3
3
  end
@@ -2,8 +2,9 @@
2
2
  #
3
3
  # testlongdecimal.rb -- runit test for long-decimal.rb
4
4
  #
5
- # (C) Karl Brodowsky (IT Sky Consulting GmbH) 2006-2009
5
+ # (C) Karl Brodowsky (IT Sky Consulting GmbH) 2006-2015
6
6
  #
7
+ # TAG: $TAG v1.00.03$
7
8
  # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/test/testlongdecimal.rb,v 1.86 2011/01/16 22:16:59 bk1 Exp $
8
9
  # CVS-Label: $Name: $
9
10
  # Author: $Author: bk1 $ (Karl Brodowsky)
@@ -1147,6 +1148,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
1147
1148
  y = Complex(yr, yi)
1148
1149
  z = x/y
1149
1150
  msg = "x=#{x} y=#{y} z=#{z} xr=#{xr.inspect} (#{tw_c}) xi=#{xi.inspect} (#{fi_c}) yr=#{yr.inspect} (#{th_c}) yi=#{yi.inspect} (#{fo_c})"
1151
+ # puts msg
1150
1152
  if (xr.kind_of? Integer) && (xi.kind_of? Integer) && (yr.kind_of? Integer) && (yi.kind_of? Integer) # && ! LongDecimal::RUNNING_19
1151
1153
  # ruby 1.9 creates rational result even from integers, ruby 1.8 uses integers as results.
1152
1154
  zc = (x.cdiv y)
@@ -2378,8 +2380,8 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
2378
2380
  #
2379
2381
  # test rounding with ROUND_HARMONIC_ODD
2380
2382
  #
2381
- def test_round_to_scale_harmonic_even
2382
- print "\ntest_round_to_scale_harmonic_even [#{Time.now}]: "
2383
+ def test_round_to_scale_harmonic_odd
2384
+ print "\ntest_round_to_scale_harmonic_odd [#{Time.now}]: "
2383
2385
  l = LongDecimal("2.39")
2384
2386
  r = l.round_to_scale(0, ROUND_HARMONIC_ODD)
2385
2387
  assert_equal("2", r.to_s, "l=#{l.inspect} r=#{r.inspect}")
@@ -2909,6 +2911,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
2909
2911
  end
2910
2912
 
2911
2913
  text0 = "m=#{modulus} x=#{x} s=#{remainders.inspect}"
2914
+ # puts text0
2912
2915
  print "."
2913
2916
  $stdout.flush
2914
2917
  n = 3*modulus
@@ -3061,6 +3064,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
3061
3064
  end
3062
3065
 
3063
3066
  text = "m=#{modulus} x=#{x} s=#{remainders.inspect}"
3067
+ # puts text
3064
3068
  print "."
3065
3069
  $stdout.flush
3066
3070
 
@@ -3527,6 +3531,11 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
3527
3531
  #
3528
3532
  def check_int_round_major_to_two_allowed_remainders(remainder_sets, boundary_exact_integral, major_mode, &block)
3529
3533
 
3534
+ if RUBY_VERSION.match /^1\.8/
3535
+ puts "Warning: this test is not supported for Ruby #{RUBY_VERSION}"
3536
+ return
3537
+ end
3538
+
3530
3539
  mode_up = MODE_LOOKUP[[major_mode, MINOR_UP]]
3531
3540
  mode_down = MODE_LOOKUP[[major_mode, MINOR_DOWN]]
3532
3541
  mode_floor = MODE_LOOKUP[[major_mode, MINOR_FLOOR]]
@@ -3534,6 +3543,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
3534
3543
 
3535
3544
  20.upto 25 do |modulus|
3536
3545
  remainder_sets.each do |remainders|
3546
+ # puts text
3537
3547
  print "."
3538
3548
  $stdout.flush
3539
3549
 
@@ -4026,6 +4036,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
4026
4036
  end
4027
4037
  end
4028
4038
  map.each do |x, x1|
4039
+ # puts "x=#{x} x1=#{x1}"
4029
4040
  print ":"
4030
4041
  $stdout.flush
4031
4042
  map.each do |y, y1|
@@ -5489,15 +5500,20 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
5489
5500
  #
5490
5501
  def test_sqrt
5491
5502
  print "\ntest_sqrt [#{Time.now}]: "
5503
+
5504
+ # sqrt of 0 is always 0 without need to round
5492
5505
  x = LongDecimal.zero!(101)
5493
5506
  y = check_sqrt(x, 120, ROUND_UNNECESSARY, 0, 0, "zero")
5494
5507
  assert(y.zero?, "sqrt(0)")
5495
5508
 
5509
+ # sqrt of 1 is always 1 without need to round
5496
5510
  x = LongDecimal.one!(101)
5497
5511
  y = check_sqrt(x, 120, ROUND_UNNECESSARY, 0, 0, "one")
5498
5512
  assert(y.one?, "sqrt(1)")
5499
5513
 
5514
+ # sqrt of 2 always gets rounded somehow
5500
5515
  x = LongDecimal.two!(101)
5516
+ x.freeze
5501
5517
  y0 = check_sqrt(x, 120, ROUND_DOWN, 0, 1, "two")
5502
5518
  assert(y0.square < x, "y0*y0")
5503
5519
  assert(y0.succ.square > x, "(y0.succ).square")
@@ -5548,6 +5564,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
5548
5564
  assert(y0 <= y1, "y0 y1")
5549
5565
  assert(y1 <= y2, "y1 y2")
5550
5566
 
5567
+ # sqrt of 3 always gets rounded somehow
5551
5568
  x = 3.to_ld
5552
5569
  y0 = check_sqrt(x, 120, ROUND_DOWN, 0, 1, "three")
5553
5570
  assert(y0.square < x, "y0*y0")
@@ -5559,6 +5576,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
5559
5576
  assert(y0 <= y1, "y0 y1")
5560
5577
  assert(y1 <= y2, "y1 y2")
5561
5578
 
5579
+ # sqrt of 4 always gets rounded somehow
5562
5580
  x = 4.to_ld(101)
5563
5581
  y0 = check_sqrt(x, 120, ROUND_DOWN, 0, 0, "four")
5564
5582
  y1 = check_sqrt(x, 120, ROUND_HALF_EVEN, 0, 0, "four")
@@ -5600,6 +5618,81 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
5600
5618
  check_sqrt_with_remainder(x, 120, "five")
5601
5619
  end
5602
5620
 
5621
+ # test sqare roots that come to lie exactly on the geometric mean of the two rounding candidates
5622
+ def test_sqrt_on_geometric_boundary
5623
+ print "\ntest_sqrt_on_geometric_boundary [#{Time.now}]: "
5624
+ 1.upto(100) do |int_val|
5625
+ 100.times do |scale|
5626
+ y_lower = LongDecimal(int_val, scale)
5627
+ y_upper = y_lower.succ
5628
+ x = y_lower * y_upper
5629
+ msg = "x=#{x} y_lower=#{y_lower} y_upper=#{y_upper} "
5630
+ # puts msg
5631
+ [ ROUND_GEOMETRIC_UP, ROUND_GEOMETRIC_CEILING ].each do |mode|
5632
+ y = LongMath.sqrt(x, scale, mode)
5633
+ assert_equal(y_upper, y, msg + "y=#{y} mode=#{mode}")
5634
+ end
5635
+ [ ROUND_GEOMETRIC_DOWN, ROUND_GEOMETRIC_FLOOR ].each do |mode|
5636
+ y = LongMath.sqrt(x, scale, mode)
5637
+ assert_equal(y_lower, y, msg + "y=#{y} mode=#{mode}")
5638
+ end
5639
+ y = LongMath.sqrt(x, scale, ROUND_GEOMETRIC_EVEN)
5640
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_GEOMETRIC_EVEN}")
5641
+ assert(y[0] == 0, msg + "y=#{y} mode=#{ROUND_GEOMETRIC_EVEN}")
5642
+ y = LongMath.sqrt(x, scale, ROUND_GEOMETRIC_ODD)
5643
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_GEOMETRIC_ODD}")
5644
+ assert(y[0] == 1, msg + "y=#{y} mode=#{ROUND_GEOMETRIC_ODD}")
5645
+ end
5646
+ end
5647
+ end
5648
+
5649
+ # test sqare roots that come to lie exactly on the geometric mean of the two rounding candidates
5650
+ def test_sqrt_zero_on_geometric_boundary
5651
+ print "\ntest_sqrt_on_geometric_boundary [#{Time.now}]: "
5652
+ 100.times do |scale|
5653
+ y_lower = LongDecimal(0, scale)
5654
+ y_upper = y_lower.succ
5655
+ x = y_lower * y_upper
5656
+ msg = "x=#{x} y_lower=#{y_lower} y_upper=#{y_upper} "
5657
+ ALL_MINOR.each do |minor|
5658
+ if (minor == MINOR_UNUSED)
5659
+ next
5660
+ end
5661
+ mode = MODE_LOOKUP[[MAJOR_GEOMETRIC, minor]]
5662
+ y = LongMath.sqrt(x, scale, mode)
5663
+ assert_equal(0, y, msg + "y=#{y} mode=#{mode}")
5664
+ end
5665
+ end
5666
+ end
5667
+
5668
+ # test sqare roots that come to lie exactly on the quadratic mean of the two rounding candidates
5669
+ def test_sqrt_on_quadratic_boundary
5670
+ print "\ntest_sqrt_on_quadratic_boundary [#{Time.now}]: "
5671
+ 100.times do |int_val|
5672
+ 100.times do |scale|
5673
+ y_lower = LongDecimal(int_val, scale)
5674
+ y_upper = y_lower.succ
5675
+ x = LongMath.arithmetic_mean(2*scale + 2, ROUND_HALF_EVEN, y_lower * y_lower, y_upper * y_upper)
5676
+ msg = "x=#{x} y_lower=#{y_lower} y_upper=#{y_upper} "
5677
+ # puts msg
5678
+ [ ROUND_QUADRATIC_UP, ROUND_QUADRATIC_CEILING ].each do |mode|
5679
+ y = LongMath.sqrt(x, scale, mode)
5680
+ assert_equal(y_upper, y, msg + "y=#{y} mode=#{mode}")
5681
+ end
5682
+ [ ROUND_QUADRATIC_DOWN, ROUND_QUADRATIC_FLOOR ].each do |mode|
5683
+ y = LongMath.sqrt(x, scale, mode)
5684
+ assert_equal(y, y_lower, msg + "y=#{y} mode=#{mode}")
5685
+ end
5686
+ y = LongMath.sqrt(x, scale, ROUND_QUADRATIC_EVEN)
5687
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_QUADRATIC_EVEN}")
5688
+ assert(y[0] == 0, msg + "y=#{y} mode=#{ROUND_QUADRATIC_EVEN}")
5689
+ y = LongMath.sqrt(x, scale, ROUND_QUADRATIC_ODD)
5690
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_QUADRATIC_ODD}")
5691
+ assert(y[0] == 1, msg + "y=#{y} mode=#{ROUND_QUADRATIC_ODD}")
5692
+ end
5693
+ end
5694
+ end
5695
+
5603
5696
  #
5604
5697
  # test LongMath.sqrt with non-LongDecimal arguments
5605
5698
  #
@@ -5740,6 +5833,34 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
5740
5833
  check_cbrt_with_remainder(x, 120, "five")
5741
5834
  end
5742
5835
 
5836
+ # test sqare roots that come to lie exactly on the cubic mean of the two rounding candidates
5837
+ def test_cbrt_on_cubic_boundary
5838
+ print "\ntest_cbrt_on_cubic_boundary [#{Time.now}]: "
5839
+ 100.times do |int_val|
5840
+ 100.times do |scale|
5841
+ y_lower = LongDecimal(int_val, scale)
5842
+ y_upper = y_lower.succ
5843
+ x = LongMath.arithmetic_mean(3*scale + 2, ROUND_HALF_EVEN, y_lower.cube(), y_upper.cube())
5844
+ msg = "x=#{x} y_lower=#{y_lower} y_upper=#{y_upper} "
5845
+ # puts msg
5846
+ [ ROUND_CUBIC_UP, ROUND_CUBIC_CEILING ].each do |mode|
5847
+ y = LongMath.cbrt(x, scale, mode)
5848
+ assert_equal(y_upper, y, msg + "y=#{y} mode=#{mode}")
5849
+ end
5850
+ [ ROUND_CUBIC_DOWN, ROUND_CUBIC_FLOOR ].each do |mode|
5851
+ y = LongMath.cbrt(x, scale, mode)
5852
+ assert_equal(y, y_lower, msg + "y=#{y} mode=#{mode}")
5853
+ end
5854
+ y = LongMath.cbrt(x, scale, ROUND_CUBIC_EVEN)
5855
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_CUBIC_EVEN}")
5856
+ assert(y[0] == 0, msg + "y=#{y} mode=#{ROUND_CUBIC_EVEN}")
5857
+ y = LongMath.cbrt(x, scale, ROUND_CUBIC_ODD)
5858
+ assert(y == y_lower || y == y_upper, msg + "y=#{y} mode=#{ROUND_CUBIC_ODD}")
5859
+ assert(y[0] == 1, msg + "y=#{y} mode=#{ROUND_CUBIC_ODD}")
5860
+ end
5861
+ end
5862
+ end
5863
+
5743
5864
  #
5744
5865
  # test LongMath.cbrt with non-LongDecimal arguments
5745
5866
  #
@@ -7354,6 +7475,46 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7354
7475
  end
7355
7476
  end
7356
7477
 
7478
+ def test_means_two_param_round_up
7479
+ print "\ntest_means_two_param_round_up [#{Time.now}] (20 sec): "
7480
+ arr = [ 0, 1, 2, 7, 0.0, 1.0, 2.0, Math::PI, Rational(40, 9), Rational(0, 1), Rational(1,1), Rational(2,3), LongDecimal(3333333333333333, 10), LongDecimal(33, 10), LongDecimal(0, 10), LongDecimal(10000000000, 10), LongMath.pi(100) ]
7481
+ x = Math::PI
7482
+ y = Math::PI
7483
+ print "."
7484
+ prec = 0
7485
+ rm = ROUND_UP
7486
+ xx = x.to_ld(prec, rm)
7487
+ yy = y.to_ld(prec, rm)
7488
+ mi = [xx, yy].min
7489
+ am = LongMath.arithmetic_mean(prec, rm, x, y)
7490
+ gm = LongMath.geometric_mean(prec, rm, x, y)
7491
+ if (x.sgn == 0 || y.sgn == 0)
7492
+ hm = gm
7493
+ else
7494
+ hm = LongMath.harmonic_mean(prec, rm, x, y)
7495
+ end
7496
+ qm = LongMath.quadratic_mean(prec, rm, x, y)
7497
+ cm = LongMath.cubic_mean(prec, rm, x, y)
7498
+ ma = [xx, yy].max
7499
+
7500
+ text = "mi=#{mi} hm=#{hm} gm=#{gm} am=#{am} qm=#{qm} cm=#{cm} ma=#{ma} prec=#{prec} rm=#{rm} x=#{x} y=#{y}"
7501
+ assert(mi <= hm.succ, text)
7502
+ assert(hm <= gm.succ, text)
7503
+ assert(gm <= am.succ, text)
7504
+ assert(am <= qm.succ, text)
7505
+ assert(qm <= cm.succ, text)
7506
+ assert(cm <= ma.succ, text)
7507
+ if (x == y)
7508
+ assert_equal(mi, hm, text)
7509
+ assert_equal(hm, gm, text)
7510
+ assert_equal(gm, am, text)
7511
+ assert_equal(am, qm, text)
7512
+ assert_equal(qm, cm, text)
7513
+ assert_equal(cm, ma, text)
7514
+ end
7515
+ end
7516
+
7517
+ # test the right ordering of the means excluding agm/hgm
7357
7518
  def test_means_three_param
7358
7519
  print "\ntest_means_three_param [#{Time.now}] (4 min): "
7359
7520
  arr = [ 0, 1, 2, 0.0, 1.0, Math::PI, Rational(40, 9), Rational(0, 1), Rational(1,1), LongDecimal(3333333333333333, 10), LongDecimal(0, 10), LongDecimal(10000000000, 10), LongMath.pi(100) ]
@@ -7363,6 +7524,60 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7363
7524
  arr.each do |z|
7364
7525
  print "."
7365
7526
  12.times do |prec|
7527
+ ALL_ROUNDING_MODES.each do |rm|
7528
+ if (rm == ROUND_UNNECESSARY)
7529
+ next
7530
+ end
7531
+ xx = x.to_ld(prec, rm)
7532
+ yy = y.to_ld(prec, rm)
7533
+ zz = z.to_ld(prec, rm)
7534
+ mi = [xx, yy, zz].min
7535
+ am = LongMath.arithmetic_mean(prec, rm, x, y, z)
7536
+ gm = LongMath.geometric_mean(prec, rm, x, y, z)
7537
+ if (x.sgn == 0 || y.sgn == 0 || z.sgn == 0)
7538
+ hm = gm
7539
+ else
7540
+ hm = LongMath.harmonic_mean(prec, rm, x, y, z)
7541
+ end
7542
+ qm = LongMath.quadratic_mean(prec, rm, x, y, z)
7543
+ cm = LongMath.cubic_mean(prec, rm, x, y, z)
7544
+ ma = [xx, yy, zz].max
7545
+ text = "mi=#{mi} hm=#{hm} gm=#{gm} am=#{am} qm=#{qm} cm=#{cm} ma=#{ma} prec=#{prec} rm=#{rm} x=#{x} y=#{y} z=#{z}"
7546
+ assert(mi <= hm.succ, text)
7547
+ assert(hm <= gm.succ, text)
7548
+ assert(gm <= am.succ, text)
7549
+ assert(am <= qm.succ, text)
7550
+ assert(qm <= cm.succ, text)
7551
+ assert(cm <= ma.succ, text)
7552
+ if (x == y && y == z)
7553
+ assert_equal(mi, hm, text)
7554
+ assert_equal(hm, gm, text)
7555
+ assert_equal(gm, am, text)
7556
+ assert_equal(am, qm, text)
7557
+ assert_equal(qm, cm, text)
7558
+ assert_equal(cm, ma, text)
7559
+ end
7560
+ end
7561
+ end
7562
+ end
7563
+ end
7564
+ end
7565
+ end
7566
+
7567
+ # test the right ordering of the means (including agm/hgm)
7568
+ def test_means_three_param_agm_hgm
7569
+ print "\ntest_means_three_param_agm_hgm [#{Time.now}] (4 min): "
7570
+ arr = [ 0, 1, 2, 0.0, 1.0, Math::PI, Rational(40, 9), Rational(0, 1), Rational(1,1), LongDecimal(3333333333333333, 10), LongDecimal(0, 10), LongDecimal(10000000000, 10), LongMath.pi(100) ]
7571
+ arr.each do |x|
7572
+ x.freeze
7573
+ arr.each do |y|
7574
+ y.freeze
7575
+ print ":"
7576
+ arr.each do |z|
7577
+ z.freeze
7578
+ print "."
7579
+ prec = 0
7580
+ 3.times do |i|
7366
7581
  ALL_ROUNDING_MODES.each do |rm|
7367
7582
  if (rm == ROUND_UNNECESSARY)
7368
7583
  next
@@ -7384,7 +7599,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7384
7599
  qm = LongMath.quadratic_mean(prec, rm, x, y, z)
7385
7600
  cm = LongMath.cubic_mean(prec, rm, x, y, z)
7386
7601
  ma = [xx, yy, zz].max
7387
- text = "mi=#{mi} hm=#{hm} gm=#{gm} am=#{am} qm=#{qm} cm=#{cm} ma=#{ma} prec=#{prec} rm=#{rm} x=#{x} y=#{y} z=#{z}"
7602
+ text = "mi=#{mi} hm=#{hm} gm=#{gm} am=#{am} qm=#{qm} cm=#{cm} ma=#{ma} prec=#{prec} rm=#{rm} x=#{x} y=#{y} z=#{z} i=#{i}"
7388
7603
  assert(mi <= hm.succ, text)
7389
7604
  assert(hm <= hgm.succ, text)
7390
7605
  assert(hgm <= gm.succ, text)
@@ -7398,12 +7613,13 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7398
7613
  assert_equal(hm, hgm, text)
7399
7614
  assert_equal(hgm, gm, text)
7400
7615
  assert_equal(gm, agm, text)
7401
- assert_equal(gm, agm, text)
7616
+ assert_equal(agm, am, text)
7402
7617
  assert_equal(am, qm, text)
7403
7618
  assert_equal(qm, cm, text)
7404
7619
  assert_equal(cm, ma, text)
7405
7620
  end
7406
7621
  end
7622
+ prec = (prec << 3) + 11
7407
7623
  end
7408
7624
  end
7409
7625
  end
@@ -7493,6 +7709,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7493
7709
  @powers_of_10[x] = zz
7494
7710
  end
7495
7711
  assert_equal(z, zz)
7712
+ # puts("exp=" + x.to_s)
7496
7713
  $stdout.flush
7497
7714
  else
7498
7715
  @powers_of_10[x] ||= z
@@ -7512,10 +7729,12 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7512
7729
 
7513
7730
  12.times do |i|
7514
7731
  check_npower10(3**i)
7732
+ # puts(3**i)
7515
7733
  end
7516
7734
 
7517
7735
  12.times do |i|
7518
7736
  check_npower10(3**i)
7737
+ # puts(3**i)
7519
7738
  end
7520
7739
 
7521
7740
  y = 1
@@ -7530,6 +7749,7 @@ class TestLongDecimal_class < UnitTest # RUNIT::TestCase
7530
7749
  x0 = 2046
7531
7750
  y0 = 10**x0
7532
7751
  60.times do |i|
7752
+ # puts "i=" + i.to_s
7533
7753
  $stdout.flush
7534
7754
  y = y0
7535
7755
  x = x0
@@ -2,8 +2,9 @@
2
2
  #
3
3
  # library for tests for long-decimal.rb and long-decimal-extra.rb
4
4
  #
5
- # (C) Karl Brodowsky (IT Sky Consulting GmbH) 2006-2009
5
+ # (C) Karl Brodowsky (IT Sky Consulting GmbH) 2006-2015
6
6
  #
7
+ # TAG: $TAG v1.00.03$
7
8
  # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/test/testlongdeclib.rb,v 1.42 2011/02/03 00:22:39 bk1 Exp $
8
9
  # CVS-Label: $Name: $
9
10
  # Author: $Author: bk1 $ (Karl Brodowsky)
@@ -26,6 +27,8 @@ end
26
27
  #
27
28
  module TestLongDecHelper
28
29
 
30
+ include LongDecimalRoundingMode
31
+
29
32
  @RCS_ID='-$Id: testlongdeclib.rb,v 1.42 2011/02/03 00:22:39 bk1 Exp $-'
30
33
 
31
34
  def assert_equal_float(lhs, rhs, delta=0, msg="")
@@ -106,8 +109,8 @@ module TestLongDecHelper
106
109
  # full_message = build_message(message, "Expected <?> to match <?> (lhs=#{lhs} rhs=#{rhs})", actual, expected)
107
110
  # assert_block(full_message) {
108
111
  # # prec = actual.scale
109
- # # ed = expected.round_to_scale(prec, LongMath::ROUND_HALF_FLOOR)
110
- # # eu = expected.round_to_scale(prec, LongMath::ROUND_HALF_CEILING)
112
+ # # ed = expected.round_to_scale(prec, ROUND_HALF_FLOOR)
113
+ # # eu = expected.round_to_scale(prec, ROUND_HALF_CEILING)
111
114
  # # # puts("ed=#{ed} eu=#{eu} e=#{expected} a=#{actual}")
112
115
  # # ed <= actual && actual <= eu
113
116
 
@@ -178,7 +181,7 @@ module TestLongDecHelper
178
181
  # eprec = prec+1
179
182
  y = LongMath.exp(x, prec)
180
183
  yy = LongMath.exp(x, prec+10)
181
- # assert_equal(yy.round_to_scale(y.scale, LongDecimal::ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
184
+ # assert_equal(yy.round_to_scale(y.scale, ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
182
185
  assert_equal_rounded(yy, y, "x=#{x} y=#{y} yy=#{yy}")
183
186
 
184
187
  # compare y against z = exp(x) calculated using regular floating point arithmetic
@@ -206,8 +209,8 @@ module TestLongDecHelper
206
209
  end
207
210
 
208
211
  # check by doing calculation with different internal rounding modes. They should not differ.
209
- yd = LongMath.exp_internal(x, prec, nil, nil, nil, nil, LongDecimal::ROUND_DOWN)
210
- yu = LongMath.exp_internal(x, prec, nil, nil, nil, nil, LongDecimal::ROUND_UP)
212
+ yd = LongMath.exp_internal(x, prec, nil, nil, nil, nil, ROUND_DOWN)
213
+ yu = LongMath.exp_internal(x, prec, nil, nil, nil, nil, ROUND_UP)
211
214
  # 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}")
212
215
  # 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}")
213
216
  assert_small_interval(yd, yu, y, "the result y/yu should not depend on the internal rounding mode x0=#{x0} x=#{x} p=#{prec} d=#{(yd-yu).to_f.to_s}")
@@ -256,7 +259,7 @@ module TestLongDecHelper
256
259
  # eprec = prec+1
257
260
  y = LongMath.exp2(x, prec)
258
261
  yy = LongMath.exp2(x, prec+10)
259
- # assert_equal(yy.round_to_scale(y.scale, LongDecimal::ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
262
+ # assert_equal(yy.round_to_scale(y.scale, ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
260
263
  assert_equal_rounded(yy, y, "x=#{x} y=#{y} yy=#{yy}")
261
264
 
262
265
  # compare y against z = exp(x) calculated using regular floating point arithmetic
@@ -303,7 +306,7 @@ module TestLongDecHelper
303
306
  # eprec = prec+1
304
307
  y = LongMath.exp10(x, prec)
305
308
  yy = LongMath.exp10(x, prec+10)
306
- # assert_equal(yy.round_to_scale(y.scale, LongDecimal::ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
309
+ # assert_equal(yy.round_to_scale(y.scale, ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
307
310
  assert_equal_rounded(yy, y, "x=#{x} y=#{y} yy=#{yy}")
308
311
 
309
312
  if (y.abs < LongMath::MAX_FLOATABLE) then
@@ -369,8 +372,8 @@ module TestLongDecHelper
369
372
  x = x.to_ld
370
373
  y = y.to_ld
371
374
 
372
- z = LongMath.power(x, y, prec, LongMath::ROUND_HALF_UP)
373
- zz = (x ** yi).round_to_scale(prec, LongMath::ROUND_HALF_UP)
375
+ z = LongMath.power(x, y, prec, ROUND_HALF_UP)
376
+ zz = (x ** yi).round_to_scale(prec, ROUND_HALF_UP)
374
377
  assert_equal(z, zz, "power with ** or power-method x=#{x} y=#{y} z=#{z} zz=#{zz}")
375
378
  zz = LongMath.power_internal(x, y, prec)
376
379
  assert((zz - z).abs <= z.unit, "power with and without optimizations x=#{x} y=#{y} z=#{z} zz=#{zz}")
@@ -394,8 +397,8 @@ module TestLongDecHelper
394
397
  x = x.to_ld
395
398
  y = LongDecimal("0.5") * y2i
396
399
 
397
- z = LongMath.power(x, y, prec, LongMath::ROUND_HALF_UP)
398
- zz = LongMath.sqrt(x ** y2i, prec, LongMath::ROUND_HALF_UP)
400
+ z = LongMath.power(x, y, prec, ROUND_HALF_UP)
401
+ zz = LongMath.sqrt(x ** y2i, prec, ROUND_HALF_UP)
399
402
  assert_equal(z, zz, "power with ** or power-method x=#{x} y=#{y} z=#{z} zz=#{zz}")
400
403
  zz = LongMath.power_internal(x, y, prec)
401
404
  assert((zz - z).abs <= z.unit, "power with and without optimizations x=#{x} y=#{y} z=#{z} zz=#{zz}")
@@ -423,7 +426,7 @@ module TestLongDecHelper
423
426
  # calculate y = log(x)
424
427
  y = LongMath.log(x, prec)
425
428
  yy = LongMath.log(x, prec+10)
426
- # assert_equal(yy.round_to_scale(y.scale, LongDecimal::ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
429
+ # assert_equal(yy.round_to_scale(y.scale, ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
427
430
  assert_equal_rounded(yy, y, "x=#{x} y=#{y} yy=#{yy}")
428
431
 
429
432
  # compare y against z = log(x) calculated using regular floating
@@ -474,10 +477,10 @@ module TestLongDecHelper
474
477
  end
475
478
 
476
479
  # check by doing calculation with different internal rounding modes. They should not differ.
477
- # yd = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_DOWN)
478
- # yu = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_UP)
479
- yd = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_FLOOR)
480
- yu = LongMath.log_internal(x, prec, nil, nil, LongDecimal::ROUND_CEILING)
480
+ # yd = LongMath.log_internal(x, prec, nil, nil, ROUND_DOWN)
481
+ # yu = LongMath.log_internal(x, prec, nil, nil, ROUND_UP)
482
+ yd = LongMath.log_internal(x, prec, nil, nil, ROUND_FLOOR)
483
+ yu = LongMath.log_internal(x, prec, nil, nil, ROUND_CEILING)
481
484
  # 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}")
482
485
  # 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}")
483
486
  assert_small_interval(yd, yu, y, "the result y/yu should not depend on the internal rounding mode x0=#{x0} x=#{x} p=#{prec} d=#{(yd-yu).to_f.to_s}")
@@ -503,7 +506,7 @@ module TestLongDecHelper
503
506
  prec_dp = 2*prec+1
504
507
  z_dp = LongMath.power(x, y, prec_dp)
505
508
  msg = "x=#{x}\ny=#{y}\nz=#{z}\nz_dp=#{z_dp}\nprec=#{prec}"
506
- puts msg
509
+ # puts msg
507
510
  assert((z - z_dp).abs <= 2*z.unit, msg)
508
511
 
509
512
  corr2 = (x - 1).abs*1000000000 # 10**9
@@ -515,23 +518,27 @@ module TestLongDecHelper
515
518
  zf = z.to_f
516
519
  qf = 1e9
517
520
  delta = [ z.unit.to_f, zf.abs / qf ].max
521
+ # puts "delta=#{delta} z=#{z} zu=#{z.unit} zuf=#{z.unit.to_f} zf=#{zf} |zf/qf|=#{zf.abs/qf}"
518
522
  if (yf.abs > 1)
519
523
  l = Math.log(yf.abs)
520
524
  if (l > 1)
521
525
  delta *= l
522
526
  end
527
+ # puts "delta=#{delta} l=#{l}"
523
528
  end
524
529
  corr = corr2 * 0.5
525
530
  if corr > 1
526
531
  corr_f = [ corr.to_f, 5.0 ].min
527
532
  delta *= corr_f
528
533
  end
534
+ # puts "delta=#{delta} corr_f=#{corr_f} corr=#{corr}"
529
535
 
530
536
  diff = (zf - wf).abs
531
537
  msg = "z=#{z}=#{zf} and wf=#{wf.to_s} should be almost equal\nx=#{x}=#{xf}\ny=#{y}=#{yf}\ndelta=#{delta}\nl=#{l}\ndiff=#{diff}\nprec=#{prec}\ncorr=#{corr}=#{corr.to_f}\ncorr2=#{corr2}=#{corr2.to_f}\ncorr_f=#{corr_f}"
532
- puts msg
538
+ # puts msg
533
539
  assert_equal_float(zf, wf, delta, msg)
534
- puts "OK"
540
+ # puts "OK"
541
+ print "."
535
542
  end
536
543
 
537
544
  # check by taking log(z) = y * log(x)
@@ -560,8 +567,8 @@ module TestLongDecHelper
560
567
  u_dp = LongMath.log(z_dp, lprec_dp)
561
568
  v = LongMath.log(x, lprec+l10y)
562
569
  v_dp = LongMath.log(x, lprec_dp + l10y)
563
- yv = (y*v).round_to_scale(lprec, LongDecimal::ROUND_HALF_DOWN)
564
- yv_dp = (y * v_dp).round_to_scale(lprec_dp, LongDecimal::ROUND_HALF_DOWN)
570
+ yv = (y*v).round_to_scale(lprec, ROUND_HALF_DOWN)
571
+ yv_dp = (y * v_dp).round_to_scale(lprec_dp, ROUND_HALF_DOWN)
565
572
  assert((u_dp - yv_dp).abs <= unit, "u=log(z,#{lprec})=#{u_dp}=#{u} and yv=y*v=y*log(x,#{lprec+l10y})=#{yv_dp}=#{yv} should be almost equal (unit=#{unit} x=#{x.to_s} y=#{y.to_s} z=#{z_dp}=#{z.to_s} u=#{u_dp}=#{u.to_s} v=#{v_dp}=#{v.to_s} lprec=#{lprec} prec=#{prec} lprec_dp=#{lprec_dp} prec_dp=#{prec_dp})")
566
573
  assert((u - yv).abs <= unit, "u=log(z,#{lprec})=#{u} and yv=y*v=y*log(x,#{lprec+l10y})=#{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})")
567
574
  end
@@ -661,7 +668,7 @@ module TestLongDecHelper
661
668
  # calculate y = log2(x)
662
669
  y = LongMath.log2(x, prec)
663
670
  yy = LongMath.log2(x, prec+10)
664
- # assert_equal(yy.round_to_scale(y.scale, LongDecimal::ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
671
+ # assert_equal(yy.round_to_scale(y.scale, ROUND_HALF_DOWN), y, "x=#{x} y=#{y} yy=#{yy}")
665
672
  assert_equal_rounded(yy, y, "x=#{x} y=#{y} yy=#{yy}")
666
673
 
667
674
  # compare y against z = log2(x) calculated using regular floating
@@ -778,13 +785,26 @@ module TestLongDecHelper
778
785
 
779
786
  #
780
787
  # helper method of test_sqrt
788
+ # su0 and su1 describe how close the sqrt should be to the ideal result in units of the result
789
+ # usually su0=0 or -1 and su1=0 or 1
781
790
  #
782
791
  def check_sqrt(x, scale, mode, su0, su1, str)
783
792
  y = x.sqrt(scale, mode)
784
- if (mode == LongMath::ROUND_HALF_UP || mode == LongMath::ROUND_HALF_DOWN || mode == LongMath::ROUND_HALF_EVEN)
793
+ if (mode == ROUND_UNNECESSARY)
794
+ ALL_ROUNDING_MODES.each do |any_mode|
795
+ if (any_mode == ROUND_UNNECESSARY)
796
+ next
797
+ end
798
+ yy = x.sqrt(scale, any_mode)
799
+ assert_equal(y, yy, "any_mode=#{any_mode}")
800
+ end
801
+ end
802
+
803
+ if (mode == ROUND_HALF_UP || mode == ROUND_HALF_DOWN || mode == ROUND_HALF_EVEN)
785
804
  yy = x.sqrt(scale+10, mode)
786
805
  assert_equal(yy.round_to_scale(y.scale, mode), y, "x=#{x} y=#{y} yy=#{yy}")
787
806
  end
807
+
788
808
  z0 = (y+su0*y.unit).square
789
809
  z1 = (y+su1*y.unit).square
790
810
  assert(0 <= y.sign, "sqrt must be >= 0" + str)
@@ -823,6 +843,7 @@ module TestLongDecHelper
823
843
  def check_cbrtb_with_remainder(x, s)
824
844
  y, r = LongMath.cbrtb_with_remainder(x)
825
845
  z0 = y.cube
846
+ # puts "x=#{x} y=#{y} z0=#{z0} r=#{r}"
826
847
  z1 = z0 + r
827
848
  z2 = (y+1).cube
828
849
  assert(0 <= y, "cbrt _with_remainder must be >= 0" + s)
@@ -836,7 +857,7 @@ module TestLongDecHelper
836
857
  #
837
858
  def check_cbrt(x, scale, mode, su0, su1, str)
838
859
  y = x.cbrt(scale, mode)
839
- if (mode == LongMath::ROUND_HALF_UP || mode == LongMath::ROUND_HALF_DOWN || mode == LongMath::ROUND_HALF_EVEN)
860
+ if (mode == ROUND_HALF_UP || mode == ROUND_HALF_DOWN || mode == ROUND_HALF_EVEN)
840
861
  yy = x.cbrt(scale+10, mode)
841
862
  assert_equal(yy.round_to_scale(y.scale, mode), y, "x=#{x} y=#{y} yy=#{yy}")
842
863
  end