flt 1.3.1 → 1.3.2

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