flt 1.0.0

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.
Files changed (56) hide show
  1. data/History.txt +41 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +42 -0
  4. data/README.txt +557 -0
  5. data/Rakefile +34 -0
  6. data/lib/flt.rb +9 -0
  7. data/lib/flt/b.rb +6 -0
  8. data/lib/flt/bigdecimal.rb +151 -0
  9. data/lib/flt/bin_num.rb +250 -0
  10. data/lib/flt/d.rb +6 -0
  11. data/lib/flt/dec_num.rb +1239 -0
  12. data/lib/flt/float.rb +458 -0
  13. data/lib/flt/math.rb +66 -0
  14. data/lib/flt/num.rb +4211 -0
  15. data/lib/flt/sugar.rb +102 -0
  16. data/lib/flt/support.rb +1335 -0
  17. data/lib/flt/tolerance.rb +561 -0
  18. data/lib/flt/tolerance/sugar.rb +77 -0
  19. data/lib/flt/version.rb +9 -0
  20. data/setup.rb +1585 -0
  21. data/tasks/ann.rake +80 -0
  22. data/tasks/bones.rake +20 -0
  23. data/tasks/gem.rake +192 -0
  24. data/tasks/git.rake +40 -0
  25. data/tasks/manifest.rake +48 -0
  26. data/tasks/notes.rake +27 -0
  27. data/tasks/post_load.rake +39 -0
  28. data/tasks/rdoc.rake +50 -0
  29. data/tasks/rubyforge.rake +55 -0
  30. data/tasks/setup.rb +279 -0
  31. data/tasks/spec.rake +54 -0
  32. data/tasks/svn.rake +47 -0
  33. data/tasks/test.rake +40 -0
  34. data/test/all_tests.rb +23 -0
  35. data/test/helper.rb +101 -0
  36. data/test/reader.rb +68 -0
  37. data/test/test_basic.rb +396 -0
  38. data/test/test_bin.rb +245 -0
  39. data/test/test_bin_arithmetic.rb +94 -0
  40. data/test/test_binfloat_conversion.rb +24 -0
  41. data/test/test_coercion.rb +22 -0
  42. data/test/test_comparisons.rb +53 -0
  43. data/test/test_dectest.rb +216 -0
  44. data/test/test_define_conversions.rb +144 -0
  45. data/test/test_epsilon.rb +55 -0
  46. data/test/test_exact.rb +147 -0
  47. data/test/test_flags.rb +34 -0
  48. data/test/test_multithreading.rb +32 -0
  49. data/test/test_num_constructor.rb +133 -0
  50. data/test/test_odd_even.rb +78 -0
  51. data/test/test_round.rb +104 -0
  52. data/test/test_to_int.rb +104 -0
  53. data/test/test_to_rf.rb +36 -0
  54. data/test/test_tol.rb +102 -0
  55. data/test/test_ulp.rb +127 -0
  56. metadata +147 -0
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestOddEven < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ initialize_context
8
+ end
9
+
10
+ def test_even
11
+ assert !DecNum.nan.even?
12
+ assert !DecNum.infinity.even?
13
+ assert !DecNum.infinity(-1).even?
14
+ assert DecNum.zero.even?
15
+ assert DecNum.zero(-1).even?
16
+ assert !DecNum('0.1').even?
17
+ assert !DecNum('-0.1').even?
18
+ assert !DecNum(-7).even?
19
+ assert DecNum(-6).even?
20
+ assert !DecNum(-5).even?
21
+ assert DecNum(-4).even?
22
+ assert !DecNum(-3).even?
23
+ assert DecNum(-2).even?
24
+ assert !DecNum(-1).even?
25
+ assert DecNum(0).even?
26
+ assert !DecNum(1).even?
27
+ assert DecNum(2).even?
28
+ assert !DecNum(3).even?
29
+ assert DecNum(4).even?
30
+ assert !DecNum(5).even?
31
+ assert DecNum(6).even?
32
+ assert !DecNum(7).even?
33
+ assert !DecNum('101').even?
34
+ assert DecNum('102').even?
35
+ assert !DecNum('103').even?
36
+ assert DecNum('10100').even?
37
+ assert DecNum('10200').even?
38
+ assert !DecNum('101.00').even?
39
+ assert DecNum('102.00').even?
40
+ assert !DecNum('101.01').even?
41
+ assert !DecNum('102.01').even?
42
+ end
43
+
44
+ def test_odd
45
+ assert !DecNum.nan.odd?
46
+ assert !DecNum.infinity.odd?
47
+ assert !DecNum.infinity(-1).odd?
48
+ assert !DecNum.zero.odd?
49
+ assert !DecNum.zero(-1).odd?
50
+ assert !DecNum('0.1').odd?
51
+ assert !DecNum('-0.1').odd?
52
+ assert DecNum(-7).odd?
53
+ assert !DecNum(-6).odd?
54
+ assert DecNum(-5).odd?
55
+ assert !DecNum(-4).odd?
56
+ assert DecNum(-3).odd?
57
+ assert !DecNum(-2).odd?
58
+ assert DecNum(-1).odd?
59
+ assert !DecNum(0).odd?
60
+ assert DecNum(1).odd?
61
+ assert !DecNum(2).odd?
62
+ assert DecNum(3).odd?
63
+ assert !DecNum(4).odd?
64
+ assert DecNum(5).odd?
65
+ assert !DecNum(6).odd?
66
+ assert DecNum(7).odd?
67
+ assert DecNum(101).odd?
68
+ assert !DecNum(102).odd?
69
+ assert DecNum(103).odd?
70
+ assert !DecNum(10100).odd?
71
+ assert !DecNum(10200).odd?
72
+ assert DecNum('101.00').odd?
73
+ assert !DecNum('102.00').odd?
74
+ assert !DecNum('101.01').odd?
75
+ assert !DecNum('102.01').odd?
76
+ end
77
+
78
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+
4
+ class TestRound < Test::Unit::TestCase
5
+
6
+
7
+ def setup
8
+ initialize_context
9
+ end
10
+
11
+
12
+ def test_round
13
+
14
+ assert_equal(101, DecNum('100.5').round)
15
+ assert DecNum('100.5').round.kind_of?(Integer)
16
+ assert_equal 100, DecNum('100.4999999999').round
17
+ assert_equal(-101, DecNum('-100.5').round)
18
+ assert_equal(-100, DecNum('-100.4999999999').round)
19
+
20
+ assert_equal 101, DecNum('100.5').round(:places=>0)
21
+ assert DecNum('100.5').round(:places=>0).kind_of?(DecNum)
22
+ assert_equal 101, DecNum('100.5').round(0)
23
+ assert DecNum('100.5').round(0).kind_of?(DecNum)
24
+
25
+ assert_equal DecNum('123.12'), DecNum('123.123').round(2)
26
+ assert_equal DecNum('123'), DecNum('123.123').round(0)
27
+ assert_equal DecNum('120'), DecNum('123.123').round(-1)
28
+ assert_equal DecNum('120'), DecNum('123.123').round(:precision=>2)
29
+ assert_equal DecNum('123.12'), DecNum('123.123').round(:precision=>5)
30
+
31
+ assert_equal 100, DecNum('100.5').round(:rounding=>:half_even)
32
+ assert_equal 101, DecNum('100.5000001').round(:rounding=>:half_even)
33
+ assert_equal 102, DecNum('101.5').round(:rounding=>:half_even)
34
+ assert_equal 101, DecNum('101.4999999999').round(:rounding=>:half_even)
35
+
36
+ assert_equal 101, DecNum('100.0001').ceil
37
+ assert_equal(-100, DecNum('-100.0001').ceil)
38
+ assert_equal(-100, DecNum('-100.9999').ceil)
39
+ assert_equal 100, DecNum('100.9999').floor
40
+ assert_equal(-101, DecNum('-100.9999').floor)
41
+ assert_equal(-101, DecNum('-100.0001').floor)
42
+
43
+ assert_equal 100, DecNum('100.99999').truncate
44
+ assert_equal(-100, DecNum('-100.99999').truncate)
45
+
46
+ assert_equal(10, DecNum('9.99999').round(:rounding=>:half_up))
47
+ assert_equal(1, DecNum('0.999999').round(:rounding=>:half_up))
48
+ assert_equal(0, DecNum('0.0999999').round(:rounding=>:half_up))
49
+ assert_equal(1, DecNum('0.0999999').round(:rounding=>:up))
50
+
51
+ end
52
+
53
+ def detect_rounding(type)
54
+ x = type.new(1)*type.int_radix_power(type.context.precision+1)
55
+ y = x + type.int_radix_power(2)
56
+ h = type.radix/2
57
+ b = h*type.radix
58
+ z = type.new(type.int_radix_power(2) - 1)
59
+ type.context do
60
+ type.context.precision = 8 if type.context.exact?
61
+ if x + 1 == y
62
+ if (y + 1 == y) && type.radix==10
63
+ :up05
64
+ elsif -x - 1 == -y
65
+ :up
66
+ else
67
+ :ceiling
68
+ end
69
+ else # x + 1 == x
70
+ if x + z == x
71
+ if -x - z == -x
72
+ :down
73
+ else
74
+ :floor
75
+ end
76
+ else # x + z == y
77
+ # round to nearest
78
+ if x + b == x
79
+ if y + b == y
80
+ :half_down
81
+ else
82
+ :half_even
83
+ end
84
+ else # x + b == y
85
+ :half_up
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def test_round_detection
93
+ [DecNum, BinNum].each do |type|
94
+ [:half_even, :half_up, :half_down, :down, :up, :floor, :ceiling, :up05].each do |rounding|
95
+ type.context(:rounding=>rounding) do
96
+ next if type==BinNum && rounding==:up05
97
+ assert_equal rounding, detect_rounding(type)
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestToInt < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ initialize_context
8
+ end
9
+
10
+ def test_to_i
11
+
12
+ assert_same 0, DecNum('0.0').to_i
13
+ assert_same 123, DecNum('0.0123000E4').to_i
14
+ assert 1234567890.eql?(DecNum('123456789E1').to_i)
15
+ assert 1234567890.eql?(DecNum('123456789000E-2').to_i)
16
+ assert_same(-123, DecNum('-0.0123000E4').to_i)
17
+ assert(-1234567890.eql?(DecNum('-123456789E1').to_i))
18
+ assert(-1234567890.eql?(DecNum('-123456789000E-2').to_i))
19
+ assert_raise(DecNum::Error) { DecNum.infinity.to_i }
20
+ assert_nil DecNum.nan.to_i
21
+ assert_same(1, DecNum('1.9').to_i)
22
+ assert_same(-1, DecNum('-1.9').to_i)
23
+
24
+ end
25
+
26
+ def test_to_integral_value
27
+
28
+ assert_equal DecNum('0'), DecNum('0.0').to_integral_value
29
+ assert_equal DecNum('123'), DecNum('0.0123000E4').to_integral_value
30
+ assert_equal DecNum('1234567890'), DecNum('123456789E1').to_integral_value
31
+ assert_equal DecNum('1234567890'), DecNum('123456789000E-2').to_integral_value
32
+ assert_equal DecNum('0'), DecNum('-0.0').to_integral_value
33
+ assert_equal DecNum('-123'), DecNum('-0.0123000E4').to_integral_value
34
+ assert_equal DecNum('-1234567890'), DecNum('-123456789E1').to_integral_value
35
+ assert_equal DecNum('-1234567890'), DecNum('-123456789000E-2').to_integral_value
36
+ DecNum.context.rounding = :half_up
37
+ assert_equal DecNum('2'), DecNum('1.9').to_integral_value
38
+ assert_equal DecNum('-2'), DecNum('-1.9').to_integral_value
39
+ DecNum.context.rounding = :down
40
+ assert_equal DecNum('1'), DecNum('1.9').to_integral_value
41
+ assert_equal DecNum('-1'), DecNum('-1.9').to_integral_value
42
+ assert DecNum.nan.to_integral_value.nan?
43
+ assert_equal DecNum.infinity, DecNum.infinity.to_integral_value
44
+
45
+ end
46
+
47
+ def test_to_integral_exact
48
+
49
+ DecNum.context.regard_flags DecNum::Rounded
50
+ DecNum.context.traps[DecNum::Rounded] = false
51
+ DecNum.context.regard_flags DecNum::Rounded
52
+ DecNum.context.traps[DecNum::Inexact] = true
53
+ assert_equal DecNum('0'), DecNum('0').to_integral_exact
54
+ assert !DecNum.context.flags[DecNum::Rounded]
55
+ assert_equal DecNum('0'), DecNum('0.0').to_integral_exact
56
+ assert !DecNum.context.flags[DecNum::Rounded]
57
+ assert_equal DecNum('123'), DecNum('123').to_integral_exact
58
+ assert !DecNum.context.flags[DecNum::Rounded]
59
+ assert_equal DecNum('123'), DecNum('0.0123000E4').to_integral_exact
60
+ assert DecNum.context.flags[DecNum::Rounded]
61
+ DecNum.context.flags[DecNum::Rounded] = false
62
+ assert_equal DecNum('1234567890'), DecNum('123456789E1').to_integral_exact
63
+ assert !DecNum.context.flags[DecNum::Rounded]
64
+ assert_equal DecNum('1234567890'), DecNum('123456789000E-2').to_integral_exact
65
+ assert DecNum.context.flags[DecNum::Rounded]
66
+ DecNum.context.flags[DecNum::Rounded] = false
67
+ assert_equal DecNum('0'), DecNum('-0.0').to_integral_exact
68
+ assert !DecNum.context.flags[DecNum::Rounded]
69
+ assert_equal DecNum('-123'), DecNum('-0.0123000E4').to_integral_exact
70
+ assert DecNum.context.flags[DecNum::Rounded]
71
+ DecNum.context.flags[DecNum::Rounded] = false
72
+ assert_equal DecNum('-1234567890'), DecNum('-123456789E1').to_integral_exact
73
+ assert !DecNum.context.flags[DecNum::Rounded]
74
+ assert_equal DecNum('-1234567890'), DecNum('-123456789000E-2').to_integral_exact
75
+ assert DecNum.context.flags[DecNum::Rounded]
76
+ DecNum.context.flags[DecNum::Rounded] = false
77
+ assert_raise(DecNum::Inexact) { DecNum('1.9').to_integral_exact }
78
+ assert DecNum.context.flags[DecNum::Rounded]
79
+ DecNum.context.flags[DecNum::Rounded] = false
80
+ assert_raise(DecNum::Inexact) { DecNum('-1.9').to_integral_exact }
81
+ assert DecNum.nan.to_integral_exact.nan?
82
+ assert_equal DecNum.infinity, DecNum.infinity.to_integral_exact
83
+ assert DecNum.context.flags[DecNum::Rounded]
84
+ DecNum.context.flags[DecNum::Rounded] = false
85
+ DecNum.context.traps[DecNum::Inexact] = false
86
+ DecNum.context.rounding = :half_up
87
+ assert_equal DecNum('2'), DecNum('1.9').to_integral_exact
88
+ assert DecNum.context.flags[DecNum::Inexact]
89
+ DecNum.context.flags[DecNum::Inexact] = false
90
+ assert_equal DecNum('-2'), DecNum('-1.9').to_integral_exact
91
+ assert DecNum.context.flags[DecNum::Inexact]
92
+ DecNum.context.flags[DecNum::Inexact] = false
93
+ DecNum.context.rounding = :down
94
+ assert_equal DecNum('1'), DecNum('1.9').to_integral_exact
95
+ assert DecNum.context.flags[DecNum::Inexact]
96
+ DecNum.context.flags[DecNum::Inexact] = false
97
+ assert_equal DecNum('-1'), DecNum('-1.9').to_integral_exact
98
+ assert DecNum.nan.to_integral_exact.nan?
99
+ assert_equal DecNum.infinity, DecNum.infinity.to_integral_exact
100
+
101
+ end
102
+
103
+
104
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestToRF < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ initialize_context
8
+ end
9
+
10
+ def test_to_r
11
+ [
12
+ [ '0', 0, 1 ],
13
+ [ '1', 1, 1 ],
14
+ [ '-1', -1, 1 ],
15
+ [ '1234567.1234567', 12345671234567, 10000000 ],
16
+ [ '-1234567.1234567', -12345671234567, 10000000 ],
17
+ [ '0.200', 2, 10 ],
18
+ [ '-0.200', -2, 10 ]
19
+ ].each do |n, num, den|
20
+ r = Rational(num,den)
21
+ d = DecNum(n)
22
+ assert d.to_r.is_a?(Rational)
23
+ assert_equal r, d.to_r
24
+ end
25
+ end
26
+
27
+ def test_to_f
28
+ ['0.1', '-0.1', '0.0', '1234567.1234567', '-1234567.1234567', '1.234E7', '1.234E-7'].each do |n|
29
+ f = Float(n)
30
+ d = DecNum(n)
31
+ assert d.to_f.is_a?(Float)
32
+ assert_equal f, d.to_f
33
+ end
34
+ end
35
+
36
+ end
data/test/test_tol.rb ADDED
@@ -0,0 +1,102 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestTolerance < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ initialize_context
8
+ float_emulation_context
9
+
10
+ DecNum.context.define_conversion_from(Float) do |x, dec_context|
11
+ BinNum.context(:rounding=>dec_context.rounding) do |bin_context|
12
+ BinNum(x).to_decimal
13
+ end
14
+ end
15
+
16
+ DecNum.context.define_conversion_from(BinNum) do |x, dec_context|
17
+ BinNum.context(:rounding=>dec_context.rounding) do |bin_context|
18
+ x.to_decimal
19
+ end
20
+ end
21
+
22
+ BinNum.context.define_conversion_from(DecNum) do |x, bin_context|
23
+ BinNum(x.to_s)
24
+ end
25
+
26
+ end
27
+
28
+ def test_absolute
29
+
30
+ tol = Tolerance(100, :absolute)
31
+ assert_equal 100, tol.value(1.0)
32
+ assert_equal 100, tol.value(1.5)
33
+ assert_equal 100, tol.value(1.0E10)
34
+ assert_equal 100, tol.value(-1.0E10)
35
+ assert_equal 100, tol.value(DecNum('1.0'))
36
+ assert_equal 100, tol.value(DecNum('1.5'))
37
+ assert_equal 100, tol.value(DecNum('1.0E10'))
38
+ assert_equal 100, tol.value(DecNum('-1.0E10'))
39
+ assert tol.eq?(11234.0, 11280.0)
40
+ assert tol.eq?(11234.0, 11135.0)
41
+ assert tol.eq?(-11234.0, -11280.0)
42
+ assert tol.eq?(DecNum('11234.0'), DecNum('11280.0'))
43
+ assert tol.eq?(DecNum('11234.0'), DecNum('11135.0'))
44
+ assert tol.eq?(DecNum('-11234.0'), DecNum('-11280.0'))
45
+ assert tol.eq?(DecNum('-11234.0'), DecNum('-11135.0'))
46
+ assert !tol.eq?(11234.0, -11280.0)
47
+ assert !tol.eq?(-11234.0, 11280.0)
48
+ assert !tol.eq?(11234.0, 11335.0)
49
+ assert !tol.eq?(11234.0, 11133.0)
50
+
51
+ end
52
+
53
+ def test_relative
54
+
55
+ tol = Tolerance(100, :relative)
56
+ assert_equal 100, tol.value(1.0)
57
+ assert_equal 150, tol.value(1.5)
58
+ assert_equal 1E12, tol.value(1.0E10)
59
+ assert_equal 1E12, tol.value(-1.0E10)
60
+ assert_equal 100, tol.value(DecNum('1.0'))
61
+ assert_equal 150, tol.value(DecNum('1.5'))
62
+ assert_equal 1E12, tol.value(DecNum('1.0E10'))
63
+ assert_equal 1E12, tol.value(DecNum('-1.0E10'))
64
+
65
+ end
66
+
67
+ def test_floating
68
+
69
+ tol = Tolerance(100, :floating)
70
+ assert_equal 100, tol.value(1.0)
71
+ assert_equal 200, tol.value(1.5)
72
+ assert_equal 100*2.0**34, tol.value(1.0E10)
73
+ assert_equal 100*2.0**34, tol.value(-1.0E10)
74
+ assert_equal 100, tol.value(DecNum('1.0'))
75
+ assert_equal 1000, tol.value(DecNum('1.5'))
76
+ assert_equal 1E12, tol.value(DecNum('1.0E10'))
77
+ assert_equal 1E12, tol.value(DecNum('-1.0E10'))
78
+
79
+ end
80
+
81
+ def test_significant_decimals
82
+ t = SigDecimalsTolerance.new(4)
83
+
84
+ assert t.eq?(DecNum('1.2345678'), DecNum('1.235'))
85
+ assert t.eq?(DecNum('12345678'), DecNum('12350000'))
86
+ assert !t.eq?(DecNum('1.2345678'), DecNum('1.234'))
87
+
88
+ end
89
+
90
+ def test_ulps
91
+ DecNum.context.precision = 4
92
+ t = UlpsTolerance.new(2)
93
+
94
+ assert t.eq?(DecNum('1.2345678'), DecNum('1.236'))
95
+ assert !t.eq?(DecNum('1.2345678'), DecNum('1.237'))
96
+ assert t.eq?(DecNum('12345678'), DecNum('12360000'))
97
+ assert !t.eq?(DecNum('12345678'), DecNum('12370000'))
98
+
99
+ end
100
+
101
+
102
+ end
data/test/test_ulp.rb ADDED
@@ -0,0 +1,127 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestUlp < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ initialize_context
8
+ end
9
+
10
+
11
+ NUMBERS = %w{
12
+ 0.0000
13
+ 0.0001
14
+ 0.0002
15
+ 0.0003
16
+ 0.0999
17
+ 0.1000
18
+ 0.1001
19
+ 0.1999
20
+ 0.2000
21
+ 0.2001
22
+ 0.8999
23
+ 0.9000
24
+ 0.9001
25
+ 0.9999
26
+ 1.0000
27
+ 1.0001
28
+ 1E27
29
+ 1.0001E27
30
+ }
31
+
32
+ def test_ulp_4dig
33
+ DecNum.context.precision = 4
34
+ DecNum.context.emin = -99
35
+ DecNum.context.emax = 99
36
+
37
+ (NUMBERS+[DecNum.zero,DecNum.zero(-1),
38
+ DecNum.context.minimum_nonzero, DecNum.context.maximum_subnormal, DecNum.context.minimum_normal,
39
+ DecNum.context.maximum_finite]).each do |n|
40
+ x = DecNum(n)
41
+ if x >= 0
42
+ assert_equal x-x.next_minus, x.ulp
43
+ else
44
+ assert_equal x.next_plus-x, x.ulp
45
+ end
46
+ end
47
+
48
+ assert_equal DecNum.context.maximum_finite-DecNum.context.maximum_finite.next_minus, DecNum.infinity.ulp
49
+ assert_equal DecNum('0.00001'), DecNum('0.1').ulp
50
+ assert_equal DecNum('1E-7'), DecNum('0.001').ulp
51
+ assert_equal DecNum('0.00001'), DecNum('0.100').ulp
52
+ assert_equal DecNum('0.00001'), DecNum('0.1000').ulp
53
+ assert_equal DecNum('0.0001'), DecNum('0.1001').ulp
54
+ assert_equal DecNum('0.0001'), DecNum('0.9').ulp
55
+ assert_equal DecNum('0.0001'), DecNum('0.99999').ulp
56
+ assert_equal DecNum('0.0001'), DecNum('0.9000').ulp
57
+ assert_equal DecNum('0.0001'), DecNum('0.990').ulp
58
+ assert_equal DecNum('0.0001'), DecNum('0.23').ulp
59
+ assert_equal DecNum('1E-101'), DecNum('1.001E-98').ulp
60
+ assert_equal DecNum('1E-102'), DecNum('1.001E-99').ulp
61
+ assert_equal DecNum('1E-102'), DecNum('1E-99').ulp
62
+ assert_equal DecNum('1E-102'), DecNum('9.99E-100').ulp
63
+ assert_equal DecNum('1E-102'), DecNum('1E-102').ulp
64
+ assert_equal DecNum('1E-102'), DecNum('0').ulp
65
+ assert_equal DecNum('1E-102'), DecNum('0').ulp
66
+
67
+ DecNum.context.exact = true
68
+ assert DecNum(1).ulp.nan?, "No ulps can be computed in exact contexts"
69
+ DecNum.context.traps[DecNum::InvalidOperation] = true
70
+ assert_raise(DecNum::InvalidOperation) { DecNum(1).ulp }
71
+
72
+ end
73
+
74
+ BIN_NUMBERS = %w{
75
+ 00000
76
+ 00001
77
+ 00010
78
+ 00011
79
+ 00111
80
+ 01000
81
+ 01001
82
+ 01111
83
+ 10000
84
+ 10001
85
+ }
86
+
87
+
88
+ def test_ulp_bin
89
+ BinNum.context.precision = 4
90
+ BinNum.context.emin = -99
91
+ BinNum.context.emax = 99
92
+
93
+ numbers = []
94
+ [0, -10, 10].each do |exp|
95
+ numbers += BIN_NUMBERS.map{|n| BinNum(+1, n.to_i(2), exp)}
96
+ numbers += BIN_NUMBERS.map{|n| BinNum(-1, n.to_i(2), exp)}
97
+ end
98
+
99
+ (numbers+[BinNum.zero,BinNum.zero(-1),
100
+ BinNum.context.minimum_nonzero, BinNum.context.maximum_subnormal, BinNum.context.minimum_normal,
101
+ BinNum.context.maximum_finite]).each do |x|
102
+ if x >= 0
103
+ assert_equal x-x.next_minus, x.ulp
104
+ else
105
+ assert_equal x.next_plus-x, x.ulp
106
+ end
107
+ end
108
+
109
+ assert_equal BinNum.context.maximum_finite-BinNum.context.maximum_finite.next_minus, BinNum.infinity.ulp
110
+ assert_equal BinNum(+1,1,-5), BinNum(+1,1,-1).ulp
111
+ assert_equal BinNum(+1,1,-7), BinNum(+1,1,-3).ulp
112
+ assert_equal BinNum(+1,1,-5), BinNum(+1,4,-3).ulp
113
+ assert_equal BinNum(+1,1,-7), BinNum(+1,4,-5).ulp
114
+ assert_equal BinNum(+1,1,-5), BinNum(+1,2**4-1,-5).ulp
115
+ assert_equal BinNum(+1,1,-7), BinNum(+1,2**4-1,-7).ulp
116
+ assert_equal BinNum(+1,1,-5), BinNum(+1,4*(2**4-1),-7).ulp
117
+ assert_equal BinNum(+1,1,-7), BinNum(+1,4*(2**4-1),-9).ulp
118
+
119
+ BinNum.context.exact = true
120
+ assert BinNum(1).ulp.nan?, "No ulps can be computed in exact contexts"
121
+ BinNum.context.traps[BinNum::InvalidOperation] = true
122
+ assert_raise(BinNum::InvalidOperation) { BinNum(1).ulp }
123
+
124
+ end
125
+
126
+
127
+ end