flt 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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