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.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/History.txt +5 -0
- data/Rakefile +1 -1
- data/lib/flt.rb +4 -0
- data/lib/flt/bigdecimal.rb +14 -0
- data/lib/flt/float.rb +19 -0
- data/lib/flt/num.rb +22 -1
- data/lib/flt/support.rb +1 -1266
- data/lib/flt/support/flag_values.rb +341 -0
- data/lib/flt/support/formatter.rb +512 -0
- data/lib/flt/support/rationalizer.rb +312 -0
- data/lib/flt/support/rationalizer_extra.rb +168 -0
- data/lib/flt/support/reader.rb +427 -0
- data/lib/flt/tolerance.rb +1 -0
- data/lib/flt/version.rb +1 -1
- data/test/data/.gitignore +4 -0
- data/test/generate_trig_data.rb +2 -2
- data/test/helper.rb +35 -0
- data/test/test_base_digits.rb +4 -4
- data/test/test_dectest.rb +2 -2
- data/test/test_exact.rb +2 -2
- data/test/test_formatter.rb +2 -2
- data/test/test_rationalizer.rb +141 -0
- data/test/test_trig.rb +1 -1
- metadata +11 -2
data/test/helper.rb
CHANGED
@@ -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)
|
data/test/test_base_digits.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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)
|
data/test/test_dectest.rb
CHANGED
@@ -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|
|
data/test/test_exact.rb
CHANGED
@@ -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
|
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
|
157
|
+
DecNum.context(:precision => :exact) do
|
158
158
|
assert DecNum.context.exact?
|
159
159
|
assert_equal 0, DecNum.context.precision
|
160
160
|
end
|
data/test/test_formatter.rb
CHANGED
@@ -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
|
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
|
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
|
data/test/test_trig.rb
CHANGED
@@ -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.
|
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-
|
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
|