flt 1.3.4 → 1.4.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.
@@ -2,6 +2,7 @@ require 'test/unit'
2
2
  $: << "." unless $:.include?(".") # for Ruby 1.9.2
3
3
  require File.expand_path(File.join(File.dirname(__FILE__),'/../lib/flt'))
4
4
  require 'enumerator'
5
+ require 'yaml'
5
6
  include Flt
6
7
 
7
8
  def initialize_context
@@ -93,6 +94,40 @@ def float_split(x)
93
94
  [Math.ldexp(s,Float::MANT_DIG).to_i,e-Float::MANT_DIG]
94
95
  end
95
96
 
97
+ def float_data
98
+ data_file = File.join(File.dirname(__FILE__) ,'data/float_data.yml')
99
+ if File.exists?(data_file)
100
+ YAML.load(File.read(data_file)).map{|x| [x].pack('H*').unpack('E')[0]}
101
+ else
102
+ srand 349842
103
+ data = []
104
+ 100.times do
105
+ x = rand
106
+ x *= rand(1000) if rand<0.5
107
+ x /= rand(1000) if rand<0.5
108
+ x *= rand(9999) if rand<0.5
109
+ x /= rand(9999) if rand<0.5
110
+ data << x
111
+ end
112
+ data << 1.0/3
113
+ data << 10.0/3
114
+ data << 100.0/3
115
+ data << 1.0/30
116
+ data << 1.0/300
117
+ data << 0.1
118
+ data << 0.01
119
+ data << 0.001
120
+ 50.times do
121
+ data << random_num(Float)
122
+ end
123
+ data += data.map{|x| -x}
124
+ data += special_nums(Float)
125
+ data += singular_nums(Float)
126
+ File.open(data_file,'w') { |out| out << data.map{|x| [x].pack('E').unpack('H*')[0].upcase }.to_yaml }
127
+ data
128
+ end
129
+ end
130
+
96
131
  def each_pair(array, &blk)
97
132
  if RUBY_VERSION>="1.9"
98
133
  array.each_slice(2,&blk)
@@ -25,25 +25,25 @@ class TestBaseDigits < Test::Unit::TestCase
25
25
 
26
26
 
27
27
  [10,15,20,100].each do |precision|
28
- DecNum.context(precision: precision) do
28
+ DecNum.context(:precision => precision) do
29
29
  assert_equal precision, DecNum.context.representable_digits(10)
30
30
  assert_equal precision, DecNum.context.necessary_digits(10)
31
31
  end
32
32
 
33
- BinNum.context(precision: precision) do
33
+ BinNum.context(:precision => precision) do
34
34
  assert_equal precision, BinNum.context.representable_digits(2)
35
35
  assert_equal precision, BinNum.context.necessary_digits(2)
36
36
  end
37
37
  end
38
38
 
39
- DecNum.context(exact: true) do
39
+ DecNum.context(:exact => true) do
40
40
  assert_nil DecNum.context.representable_digits(10)
41
41
  assert_nil DecNum.context.necessary_digits(10)
42
42
  assert_nil DecNum.context.representable_digits(2)
43
43
  assert_nil DecNum.context.necessary_digits(2)
44
44
  end
45
45
 
46
- BinNum.context(exact: true) do
46
+ BinNum.context(:exact => true) do
47
47
  assert_nil BinNum.context.representable_digits(10)
48
48
  assert_nil BinNum.context.necessary_digits(10)
49
49
  assert_nil BinNum.context.representable_digits(2)
@@ -112,9 +112,9 @@ class TestBasic < Test::Unit::TestCase
112
112
 
113
113
  def test_dec
114
114
  missing = []
115
- dir = File.join(File.dirname(__FILE__), 'dectest')
115
+ dir = File.join(File.dirname(__FILE__), 'data/dectest')
116
116
  if !File.exists?(dir)
117
- skip "No dectest data present. Get it from http://speleotrove.com/decimal/dectest.zip and put it in test/dectest"
117
+ skip "No dectest data present. Get it from http://speleotrove.com/decimal/dectest.zip and put it in test/data/dectest"
118
118
  return
119
119
  end
120
120
  Dir[File.join(dir, '*.decTest')].each do |fn|
@@ -148,13 +148,13 @@ class TestExact < Test::Unit::TestCase
148
148
  DecNum.context.precision = 10
149
149
  refute DecNum.context.exact?
150
150
  assert_equal 10, DecNum.context.precision
151
- DecNum.context(exact: true) do
151
+ DecNum.context(:exact => true) do
152
152
  assert DecNum.context.exact?
153
153
  assert_equal 0, DecNum.context.precision
154
154
  end
155
155
  refute DecNum.context.exact?
156
156
  assert_equal 10, DecNum.context.precision
157
- DecNum.context(precision: :exact) do
157
+ DecNum.context(:precision => :exact) do
158
158
  assert DecNum.context.exact?
159
159
  assert_equal 0, DecNum.context.precision
160
160
  end
@@ -60,7 +60,7 @@ class TestExact < Test::Unit::TestCase
60
60
 
61
61
  def test_binary_to_repeating_decimal_formatter
62
62
  Flt::BinNum.context = Flt::BinNum::IEEEDoubleContext
63
- formatter = Flt::Support::Formatter.new(BinNum.radix, BinNum.context.etiny, 10, raise_on_repeat: false)
63
+ formatter = Flt::Support::Formatter.new(BinNum.radix, BinNum.context.etiny, 10, :raise_on_repeat => false)
64
64
 
65
65
  x = BinNum(0.1)
66
66
  s, f, e = x.split
@@ -154,7 +154,7 @@ def test_binary_to_repeating_decimal_formatter
154
154
 
155
155
  def test_decimal_to_repeating_binary_formatter
156
156
  Flt::DecNum.context.precision = 8
157
- formatter = Flt::Support::Formatter.new(DecNum.radix, DecNum.context.etiny, 2, raise_on_repeat: false)
157
+ formatter = Flt::Support::Formatter.new(DecNum.radix, DecNum.context.etiny, 2, :raise_on_repeat => false)
158
158
 
159
159
  x = DecNum('0.1')
160
160
  s, f, e = x.split
@@ -0,0 +1,141 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ require 'flt/math'
4
+ require 'bigdecimal/math'
5
+
6
+ if RUBY_VERSION>="1.9.2"
7
+ BgMth = BigMath
8
+ else
9
+ module BgMth
10
+ extend BigMath
11
+ end
12
+ end
13
+
14
+ class TestRationalizer < Test::Unit::TestCase
15
+
16
+ def setup
17
+ initialize_context
18
+ Flt::DecNum.context = Flt::DecNum::DefaultContext
19
+ @data = float_data
20
+ end
21
+
22
+ R = Flt::Support::Rationalizer
23
+
24
+ def test_basic_rationalizer
25
+ # basic Rationalizer tests
26
+ r = R.new
27
+ assert_equal [13,10], r.rationalize(1.3)
28
+ assert_equal [13,10], R.max_denominator(1.3,10)
29
+ assert_equal [13,10], R.max_denominator(BigDecimal('1.3'),10)
30
+ assert_equal [1,3], R.max_denominator(1.0/3,10)
31
+ assert_equal [1,3], R.max_denominator(BigDecimal('1')/3,10)
32
+ assert_equal [13,10], R.max_denominator(Flt.DecNum('1.3'),10)
33
+ assert_equal [1,3], R.max_denominator(Flt.DecNum('1')/3,10)
34
+
35
+ # basic tests of Float.context.rationalize
36
+ assert_equal Rational(1,3), Float.context.rationalize(1.0/3.0)
37
+ assert_equal Rational(2,3), Float.context.rationalize(2.0/3.0)
38
+ assert_equal Rational(1237,1234), Float.context.rationalize(1237.0/1234.0)
39
+ assert_equal Rational(89,217), Float.context.rationalize(89.0/217.0)
40
+
41
+ # rationalization of Floats using a tolerance
42
+ t = Flt.Tolerance(1e-15/2,:floating)
43
+ assert_equal Rational(540429, 12500), Float.context.rationalize(43.23432, t, :strict)
44
+ assert_equal Rational(6636649, 206596193), Float.context.rationalize(0.032123772, t, :strict)
45
+ assert_equal Rational(280943, 2500000), Float.context.rationalize(0.1123772, t, :strict)
46
+ assert_equal Rational(39152929, 12500), Float.context.rationalize(3132.23432, t, :strict)
47
+ assert_equal Rational(24166771439, 104063), Float.context.rationalize(232232.123223432, t, :strict)
48
+ assert_equal Rational(792766404965, 637), Float.context.rationalize(1244531247.98273123, t, :strict)
49
+
50
+ # @data.each do |x|
51
+ # assert t.eq?(x, Float.context.rationalize(x,t).to_f), "out of tolerance: #{x.inspect}"
52
+ # end
53
+
54
+ # rationalization with maximum denominator
55
+ assert_equal Rational(9441014047197, 7586), Float.context.rationalize(1244531247.98273123, 10000)
56
+ assert_equal Rational(11747130449709, 9439), BigDecimal.context.rationalize(BigDecimal('1244531247.982731230'), 10000)
57
+
58
+ assert_equal Rational(11747130449709, 9439), Flt::DecNum.context.rationalize(Flt::DecNum('1244531247.982731230'), 10000)
59
+
60
+ # approximate a value in [0.671,0.672];
61
+ # Float
62
+ assert_equal [43,64], R[Flt.Tolerance(0.0005)].rationalize(0.6715)
63
+ assert_equal [43,64], R[Rational(5,10000)].rationalize(0.6715)
64
+ # BinNum
65
+ assert_equal [43,64], R[Flt.Tolerance(Flt.BinNum('0.0005'))].rationalize(Flt::BinNum('0.6715'))
66
+ assert_equal [43,64], R[Flt.Tolerance(Rational(5,10000))].rationalize(Flt::BinNum('0.6715'))
67
+ # BigDecimal
68
+ assert_equal [43,64], R[Flt.Tolerance('0.0005')].rationalize(BigDecimal('0.6715'))
69
+ assert_equal [43,64], R[Rational(5,10000)].rationalize(BigDecimal('0.6715'))
70
+ # DecNum
71
+ assert_equal [43,64], R[Flt.Tolerance(Flt.DecNum('0.0005'))].rationalize(Flt::DecNum('0.6715'))
72
+ assert_equal [43,64], R[Flt.Tolerance(Rational(5,10000))].rationalize(Flt::DecNum('0.6715'))
73
+ #
74
+ assert_equal Rational(43,64), Float.context.rationalize(0.6715, 0.0005)
75
+ assert_equal Rational(43,64), Float.context.rationalize(0.6715, Rational(5,10000))
76
+ assert_equal Rational(47,70), Float.context.rationalize(0.6715, 70)
77
+ assert_equal Rational(45,67), Float.context.rationalize(0.6715, 69)
78
+ assert_equal Rational(2,3), Float.context.rationalize(0.6715, 10)
79
+
80
+ # some PI tests
81
+ assert_equal Rational(899125804609,286200632530), BigDecimal.context.rationalize(BgMth.PI(64), Flt.Tolerance(Flt.DecNum('261E-24')))
82
+ assert_equal Rational(899125804609,286200632530), BigDecimal.context.rationalize(BgMth.PI(64), Flt.Tolerance(Flt.DecNum('261E-24')))
83
+ assert_equal Rational(899125804609,286200632530), BigDecimal.context.rationalize(BgMth.PI(64), Flt.DecNum('261E-24'))
84
+ assert_equal Rational(899125804609,286200632530), BigDecimal.context.rationalize(BgMth.PI(64), 261E-24)
85
+
86
+ assert_equal Rational(899125804609,286200632530), Flt::DecNum.context.rationalize(Flt::DecNum::Math.pi(64), Flt.Tolerance(Flt.DecNum('261E-24')))
87
+ assert_equal Rational(899125804609,286200632530), Flt::DecNum.context.rationalize(Flt::DecNum::Math.pi(64), Flt.Tolerance(Flt.DecNum('261E-24')))
88
+ assert_equal Rational(899125804609,286200632530), Flt::DecNum.context.rationalize(Flt::DecNum::Math.pi(64), Flt.DecNum('261E-24'))
89
+ assert_equal Rational(899125804609,286200632530), Flt::DecNum.context.rationalize(Flt::DecNum::Math.pi(64), 261E-24)
90
+
91
+ # DecNum tests
92
+ #t = Flt.Tolerance(Flt.DecNum('1e-15'),:floating)
93
+ t = Flt.Tolerance(20, :sig_decimals)
94
+ @data.each do |x|
95
+ x = Flt.BinNum(x).to_decimal_exact
96
+ next if x.special?
97
+ q = x.rationalize(t)
98
+ assert t.eq?(x, Flt.DecNum(q)), "out of tolerance: #{x.inspect} #{Flt.DecNum(q)}"
99
+ end
100
+
101
+ # Flt tests
102
+ #t = Flt.Tolerance(Flt.DecNum('1e-15'),:floating)
103
+ t = Flt.Tolerance(20,:sig_decimals)
104
+ @data.each do |x|
105
+ x = Flt.BinNum(x)
106
+ next if x.special?
107
+ q = x.rationalize(t)
108
+ assert t.eq?(x, Flt.BinNum(q)), "out of tolerance: #{x.inspect} #{Flt.BinNum(q)}"
109
+ end
110
+ end
111
+
112
+ def test_compare_algorithms
113
+ r = R[Flt.Tolerance(1e-5,:floating)]
114
+ @data.each do |x|
115
+ q1 = r.rationalize_Knuth(x)
116
+ q2 = r.rationalize_Horn(x)
117
+ q3 = r.rationalize_HornHutchins(x)
118
+ #q4 = r.rationalize_KnuthB(x)
119
+ q1 = [-q1[0],-q1[1]] if q1[1] < 0
120
+ q2 = [-q2[0],-q2[1]] if q2[1] < 0
121
+ q3 = [-q3[0],-q3[1]] if q3[1] < 0
122
+ assert_equal q1, q2
123
+ assert_equal q1, q3
124
+ #assert_equal q1, q4
125
+ end
126
+ r = R[Flt.Tolerance(:epsilon)]
127
+ @data.each do |x|
128
+ q1 = r.rationalize_Knuth(x)
129
+ q2 = r.rationalize_Horn(x)
130
+ q3 = r.rationalize_HornHutchins(x)
131
+ q1 = [-q1[0],-q1[1]] if q1[1] < 0
132
+ q2 = [-q2[0],-q2[1]] if q2[1] < 0
133
+ q3 = [-q3[0],-q3[1]] if q3[1] < 0
134
+ #q4 = r.rationalize_KnuthB(x)
135
+ assert_equal q1, q2
136
+ assert_equal q1, q3
137
+ #assert_equal q1, q4
138
+ end
139
+ end
140
+
141
+ end
@@ -6,7 +6,7 @@ class TestTrig < Test::Unit::TestCase
6
6
 
7
7
  def setup
8
8
  @data = {}
9
- Dir[File.join(File.dirname(__FILE__), "trigtest/*.txt")].each do |fn|
9
+ Dir[File.join(File.dirname(__FILE__), "data/trigtest/*.txt")].each do |fn|
10
10
  if File.basename(fn) =~ /\A([a-z]+)(\d+)_(\d+)_([a-z]+)\.txt\Z/
11
11
  method = $1.to_sym
12
12
  radix = $2.to_i
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Goizueta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-27 00:00:00.000000000 Z
11
+ date: 2014-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,12 +67,18 @@ files:
67
67
  - lib/flt/num.rb
68
68
  - lib/flt/sugar.rb
69
69
  - lib/flt/support.rb
70
+ - lib/flt/support/flag_values.rb
71
+ - lib/flt/support/formatter.rb
72
+ - lib/flt/support/rationalizer.rb
73
+ - lib/flt/support/rationalizer_extra.rb
74
+ - lib/flt/support/reader.rb
70
75
  - lib/flt/tolerance.rb
71
76
  - lib/flt/tolerance/sugar.rb
72
77
  - lib/flt/trigonometry.rb
73
78
  - lib/flt/version.rb
74
79
  - setup.rb
75
80
  - test/all_tests.rb
81
+ - test/data/.gitignore
76
82
  - test/generate_trig_data.rb
77
83
  - test/helper.rb
78
84
  - test/reader.rb
@@ -93,6 +99,7 @@ files:
93
99
  - test/test_multithreading.rb
94
100
  - test/test_num_constructor.rb
95
101
  - test/test_odd_even.rb
102
+ - test/test_rationalizer.rb
96
103
  - test/test_round.rb
97
104
  - test/test_sugar.rb
98
105
  - test/test_to_int.rb
@@ -126,6 +133,7 @@ specification_version: 4
126
133
  summary: Floating Point Numbers
127
134
  test_files:
128
135
  - test/all_tests.rb
136
+ - test/data/.gitignore
129
137
  - test/generate_trig_data.rb
130
138
  - test/helper.rb
131
139
  - test/reader.rb
@@ -146,6 +154,7 @@ test_files:
146
154
  - test/test_multithreading.rb
147
155
  - test/test_num_constructor.rb
148
156
  - test/test_odd_even.rb
157
+ - test/test_rationalizer.rb
149
158
  - test/test_round.rb
150
159
  - test/test_sugar.rb
151
160
  - test/test_to_int.rb