flt 1.3.1 → 1.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4361f2aa54884af4cc140d8caa5e7575b57faded
4
- data.tar.gz: 98b581886ff91b9ba8be1ca2cf0030f4d0a6878b
3
+ metadata.gz: 64bc0f97cc0f1ece8bdc24b6ff7dd03bb1d2e171
4
+ data.tar.gz: 6c897e66afe636591ab5e79073e612d9518a6ddf
5
5
  SHA512:
6
- metadata.gz: d600399045683b9ac8b7db526f3c7f4065bc98f869076b829ea165dece35a6c630b723d694c2bf642af148ca19efe624af68a3749f24a011ca501462aa3ac111
7
- data.tar.gz: ca163347091dbb34ec079438b54583b759cf6e334a0d4305f668d1de4838e13fceb53726bad9b41fdedb435f0856686df9a62815fccf23af2c9170d7f804d011
6
+ metadata.gz: 3b180c058fe8c16f9815b1add0af0078e25a2e91021088580729e7789ddf4b658104db3feeef2dd454d228b06a24fd051f94b73b88584cba8f8dbd1c2239d28a
7
+ data.tar.gz: a41979f3f15dc331e3361c0407e54f96d36825d9c4b67ee3133dcdf6b439905f52e540854956a1258db9db6800368773c7cfd3d1f1380377bdf4f4afe2ecfe40
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 1.3.2 2014-10-07
2
+
3
+ logb now complies with the context precision
4
+
1
5
  == 1.3.1 2014-05-19
2
6
 
3
7
  Removed dependencies: Jeweler, Shoulda; using Gemfile
data/README.rdoc CHANGED
@@ -10,7 +10,7 @@ could be improved in the future by using a C extension based on the decNumber li
10
10
  The Flt::Tolerance classes and the Flt.Tolerance() constructor handle floating point
11
11
  tolerances defined in flexible ways.
12
12
 
13
- Context classes are define in the files
13
+ Context classes are defined in the files
14
14
  flt/float.rb[link:lib/flt/float_rb.html] and
15
15
  flt/bigdecimal.rb[link:lib/flt/bigdecimal_rb.html]
16
16
  for Float and BigDecimal numbers that aid to the interchangeability of floating point types. This
data/Rakefile CHANGED
@@ -17,3 +17,5 @@ Rake::RDocTask.new do |rdoc|
17
17
  rdoc.rdoc_files.include('README*')
18
18
  rdoc.rdoc_files.include('lib/**/*.rb')
19
19
  end
20
+
21
+ task default: :test
data/lib/flt/num.rb CHANGED
@@ -2347,7 +2347,7 @@ class Num < Numeric
2347
2347
  return ans if ans
2348
2348
  return num_class.infinity if infinite?
2349
2349
  return context.exception(DivisionByZero,'logb(0)',-1) if zero?
2350
- Num(adjusted_exponent)
2350
+ Num(adjusted_exponent)._fix(context)
2351
2351
  end
2352
2352
 
2353
2353
  # Adds a value to the exponent.
@@ -2993,7 +2993,7 @@ class Num < Numeric
2993
2993
  # :precision 1 2 3 4 5 6 7 8
2994
2994
  # :power 1E3 1E2 10 1 0.1 1E-2 1E-3 1E-4
2995
2995
  # :index 0 1 2 3 4 5 6 7
2996
- # :index 7 6 5 4 3 2 1 0
2996
+ # :rindex 7 6 5 4 3 2 1 0
2997
2997
  def round(opt={})
2998
2998
  opt = { :places=>opt } if opt.kind_of?(Integer)
2999
2999
  r = opt[:rounding] || :half_up
data/lib/flt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Flt
2
- VERSION = "1.3.1"
2
+ VERSION = "1.3.2"
3
3
  end
data/test/test_dectest.rb CHANGED
@@ -63,6 +63,7 @@ PENDING = %w{
63
63
  minmag
64
64
  comparetotal
65
65
  comparetotmag
66
+ comparesig
66
67
  }
67
68
  IGNORED = PENDING + %w{
68
69
  copy
@@ -110,97 +111,98 @@ end
110
111
  class TestBasic < Test::Unit::TestCase
111
112
 
112
113
  def test_dec
113
- missing = []
114
+ missing = []
114
115
  dir = File.join(File.dirname(__FILE__), 'dectest')
115
- dir = nil unless File.exists?(dir)
116
- if dir
117
- Dir[File.join(dir, '*.decTest')].each do |fn|
118
-
119
- name = File.basename(fn,'.decTest').downcase
120
- next if %w{ds dd dq}.include?(name[0,2]) ||
121
- %w{decsingle decdouble decquad testall}.include?(name)
122
-
123
- initialize_context
124
-
125
-
126
- File.open(fn,'r') do |file|
127
- file.each_line do |line|
128
- line = line.split('--').first.strip if line.include?('--')
129
- next if line.strip.empty?
130
-
131
- if line.include?(' -> ')
132
- # test
133
- # to do :remove inline comments --... on the right of ->
134
- sides = line.split('->')
135
- # now split by whitespace but avoid breaking quoted strings (and take care or repeated quotes!)
136
- lhs = sides.first.strip.scan(/"(?:[^"]|"")*"|'(?:[^']|'')*'|\S+/)
137
- id = lhs.first
138
- funct = lhs[1].downcase
139
- valstemp = lhs[2..-1]
140
- rhs = sides.last.strip.split
141
- ans = rhs.first
142
- flags = rhs[1..-1].map{|f| DecNum.class_eval(FLAG_NAMES[f.downcase].to_s)}.compact
143
-
144
- next unless valstemp.grep(/#/).empty?
145
-
146
- $test_id = id
147
- funct = FUNCTIONS[original_funct=funct]
148
- next if EXCEPTIONS.include?(id)
149
- if funct
150
- # do test
151
- msg = " Test #{id}: #{funct}(#{valstemp.join(',')}) = #{ans}"
152
- #File.open('dectests.txt','a'){|f| f.puts msg}
153
- expected = result = result_flags = nil
154
- DecNum.local_context do |context|
155
- context.flags.clear!
156
- exact_input = !['apply','to_sci_string', 'to_eng_string'].include?(funct)
157
- if exact_input
158
- p = context.precision
159
- context.exact = true
160
- end
161
- valstemp.map!{|v| DecNum(unquote(v))}
162
- context.precision = p if exact_input
163
- result = context.send(funct, *valstemp)
164
- result_flags = context.flags.dup
165
- expected = unquote(ans)
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"
118
+ return
119
+ end
120
+ Dir[File.join(dir, '*.decTest')].each do |fn|
121
+
122
+ name = File.basename(fn,'.decTest').downcase
123
+ next if %w{ds dd dq}.include?(name[0,2]) ||
124
+ %w{decsingle decdouble decquad testall}.include?(name)
125
+
126
+ initialize_context
127
+
128
+
129
+ File.open(fn,'r') do |file|
130
+ file.each_line do |line|
131
+ line = line.split('--').first.strip if line.include?('--')
132
+ next if line.strip.empty?
133
+
134
+ if line.include?(' -> ')
135
+ # test
136
+ # to do :remove inline comments --... on the right of ->
137
+ sides = line.split('->')
138
+ # now split by whitespace but avoid breaking quoted strings (and take care or repeated quotes!)
139
+ lhs = sides.first.strip.scan(/"(?:[^"]|"")*"|'(?:[^']|'')*'|\S+/)
140
+ id = lhs.first
141
+ funct = lhs[1].downcase
142
+ valstemp = lhs[2..-1]
143
+ rhs = sides.last.strip.split
144
+ ans = rhs.first
145
+ flags = rhs[1..-1].map{|f| DecNum.class_eval(FLAG_NAMES[f.downcase].to_s)}.compact
146
+
147
+ next unless valstemp.grep(/#/).empty?
148
+
149
+ $test_id = id
150
+ funct = FUNCTIONS[original_funct=funct]
151
+ next if EXCEPTIONS.include?(id)
152
+ if funct
153
+ # do test
154
+ msg = " Test #{id}: #{funct}(#{valstemp.join(',')}) = #{ans} : #{name} [#{line}]"
155
+ #File.open('dectests.txt','a'){|f| f.puts msg}
156
+ expected = result = result_flags = nil
157
+ DecNum.local_context do |context|
158
+ context.flags.clear!
159
+ exact_input = !['apply','to_sci_string', 'to_eng_string'].include?(funct)
160
+ if exact_input
161
+ p = context.precision
166
162
  context.exact = true
167
- expected = DecNum(expected) unless result.is_a?(String)
168
- end
169
- result = 1 if result==true
170
- result = 0 if result==false
171
- expected_flags = DecNum::Flags(*flags)
172
- if ans!='?'
173
- assert_equal expected.to_s, result.to_s, msg
174
163
  end
175
- assert_equal expected_flags, result_flags, msg
176
-
177
- else
178
- missing << original_funct unless IGNORED.include?(original_funct) || missing.include?(original_funct)
164
+ valstemp.map!{|v| DecNum(unquote(v))}
165
+ context.precision = p if exact_input
166
+ result = context.send(funct, *valstemp)
167
+ result_flags = context.flags.dup
168
+ expected = unquote(ans)
169
+ context.exact = true
170
+ expected = DecNum(expected) unless result.is_a?(String)
179
171
  end
180
-
181
- elsif line.include?(':')
182
- # directive
183
- funct,value = line.split(':').map{|x| x.strip.downcase}
184
- case funct
185
- when 'rounding'
186
- value = ROUNDINGS[value]
187
- else
188
- value = value.to_i
172
+ result = 1 if result==true
173
+ result = 0 if result==false
174
+ expected_flags = DecNum::Flags(*flags)
175
+ if ans!='?'
176
+ assert_equal expected.to_s, result.to_s, msg
189
177
  end
190
- if value.nil?
191
- #raise "error"
192
- # to do: skip untill next valid value of same funct
178
+ assert_equal expected_flags, result_flags, msg
179
+
180
+ else
181
+ missing << original_funct unless IGNORED.include?(original_funct) || missing.include?(original_funct)
182
+ end
183
+
184
+ elsif line.include?(':')
185
+ # directive
186
+ funct,value = line.split(':').map{|x| x.strip.downcase}
187
+ case funct
188
+ when 'rounding'
189
+ value = ROUNDINGS[value]
193
190
  else
194
- case funct
195
- when 'rounding','precision'
196
- DecNum.context.send "#{funct}=", value
197
- when 'maxexponent'
198
- DecNum.context.emax = value
199
- when 'minexponent'
200
- DecNum.context.emin = value
201
- when 'clamp'
202
- DecNum.context.clamp = (value==0 ? false : true)
203
- end
191
+ value = value.to_i
192
+ end
193
+ if value.nil?
194
+ #raise "error"
195
+ # to do: skip untill next valid value of same funct
196
+ else
197
+ case funct
198
+ when 'rounding','precision'
199
+ DecNum.context.send "#{funct}=", value
200
+ when 'maxexponent'
201
+ DecNum.context.emax = value
202
+ when 'minexponent'
203
+ DecNum.context.emin = value
204
+ when 'clamp'
205
+ DecNum.context.clamp = (value==0 ? false : true)
204
206
  end
205
207
  end
206
208
  end
data/test/test_trig.rb CHANGED
@@ -24,57 +24,77 @@ class TestTrig < Test::Unit::TestCase
24
24
  BinNum.context = BinNum::IEEEDoubleContext
25
25
  end
26
26
 
27
+ def trig_test_data_present?(radix, angle)
28
+ present = @data && @data[radix] && @data[radix][angle]
29
+ skip unless present
30
+ present
31
+ end
32
+
27
33
  def check(f, radix=10, angle=:rad)
28
- class_num = Num[radix]
29
- @data[radix][angle].keys.each do |prec|
30
- class_num.context(:precision=>prec, :angle=>angle) do
31
- class_num.context.traps[DecNum::DivisionByZero] = false
32
- data = @data[radix][angle][prec][f]
33
- data.each do |x, result|
34
- assert_equal result, class_num::Math.send(f, x), "#{f}(#{x})==#{result}\ninput: #{x.to_int_scale.inspect} [#{radix} #{angle} #{prec}]"
34
+ if trig_test_data_present?(radix, angle)
35
+ class_num = Num[radix]
36
+ @data[radix][angle].keys.each do |prec|
37
+ class_num.context(:precision=>prec, :angle=>angle) do
38
+ class_num.context.traps[DecNum::DivisionByZero] = false
39
+ data = @data[radix][angle][prec][f]
40
+ data.each do |x, result|
41
+ msg = "#{f}(#{x})==#{result}\ninput: #{x.to_int_scale.inspect} [#{radix} #{angle} #{prec}]"
42
+ assert_equal result, class_num::Math.send(f, x), msg
43
+ end
35
44
  end
36
45
  end
37
46
  end
38
47
  end
39
48
 
40
49
  def check_relaxed(f, radix=10, angle=:rad, ulps=1)
41
- class_num = Num[radix]
42
- @data[radix][angle].keys.each do |prec|
43
- class_num.context(:precision=>prec, :angle=>angle) do
44
- class_num.context.traps[DecNum::DivisionByZero] = false
45
- data = @data[radix][angle][prec][f]
46
- unless data.nil?
47
- data.each do |x, result|
48
- y = class_num::Math.send(f, x)
49
- if result.special?
50
- assert_equal result, y, "#{f}(#{x})==#{result} [#{radix} #{angle} #{prec}]"
51
- else
52
- err_ulps = (y-result).abs/result.ulp
53
- assert err_ulps<=ulps, "#{f}(#{x})==#{result} to within #{ulps} ulps; error: #{err_ulps} ulps (#{y})\ninput: #{x.to_int_scale.inspect} [#{radix} #{angle} #{prec}]"
50
+ if trig_test_data_present?(radix, angle)
51
+ class_num = Num[radix]
52
+ @data[radix][angle].keys.each do |prec|
53
+ class_num.context(:precision=>prec, :angle=>angle) do
54
+ class_num.context.traps[DecNum::DivisionByZero] = false
55
+ data = @data[radix][angle][prec][f]
56
+ unless data.nil?
57
+ data.each do |x, result|
58
+ y = class_num::Math.send(f, x)
59
+ if result.special?
60
+ assert_equal result, y, "#{f}(#{x})==#{result} [#{radix} #{angle} #{prec}]"
61
+ else
62
+ err_ulps = (y-result).abs/result.ulp
63
+ msg = "#{f}(#{x})==#{result} to within #{ulps} ulps; error: #{err_ulps} ulps (#{y})\ninput: #{x.to_int_scale.inspect} [#{radix} #{angle} #{prec}]"
64
+ assert err_ulps<=ulps, msg
65
+ end
54
66
  end
67
+ else
68
+ skip "Missing data for radix #{radix.inspect} angle #{angle.inspect} prec #{prec.inspect} #{f.inspect}"
55
69
  end
56
- else
57
- STDERR.puts "Missing data for radix #{radix.inspect} angle #{angle.inspect} prec #{prec.inspect} #{f.inspect}"
58
70
  end
59
71
  end
60
72
  end
61
73
  end
62
74
 
63
75
  def check_bin(f)
64
- class_num = BinNum
65
- @data[2][:rad].keys.each do |prec|
66
- class_num.context do
67
- #class_num.context.traps[DecNum::DivisionByZero] = false
68
- data = @data[2][:rad][53][f]
69
- data.each do |x, result|
70
- x = class_num.Num(x)
71
- result = ::Math.send(f, x.to_f)
72
- assert_equal result, class_num::Math.send(f, x), "#{f}(#{x})==#{result} [bin]"
76
+ if trig_test_data_present?(2, :rad)
77
+ class_num = BinNum
78
+ @data[2][:rad].keys.each do |prec|
79
+ class_num.context do
80
+ #class_num.context.traps[DecNum::DivisionByZero] = false
81
+ data = @data[2][:rad][53][f]
82
+ data.each do |x, result|
83
+ x = class_num.Num(x)
84
+ result = ::Math.send(f, x.to_f)
85
+ assert_equal result, class_num::Math.send(f, x), "#{f}(#{x})==#{result} [bin]"
86
+ end
73
87
  end
74
88
  end
75
89
  end
76
90
  end
77
91
 
92
+ def test_data_present
93
+ if @data.empty?
94
+ skip "No data for trigonometry tests. Generate it with tst/generate_trig_data.rb"
95
+ end
96
+ end
97
+
78
98
  def test_sin
79
99
  check :sin, 10, :rad
80
100
  end
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.1
4
+ version: 1.3.2
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-05-19 00:00:00.000000000 Z
11
+ date: 2014-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler