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
data/tasks/test.rake ADDED
@@ -0,0 +1,40 @@
1
+
2
+ if test(?e, PROJ.test.file) or not PROJ.test.files.to_a.empty?
3
+ require 'rake/testtask'
4
+
5
+ namespace :test do
6
+
7
+ Rake::TestTask.new(:run) do |t|
8
+ t.libs = PROJ.libs
9
+ t.test_files = if test(?f, PROJ.test.file) then [PROJ.test.file]
10
+ else PROJ.test.files end
11
+ t.ruby_opts += PROJ.ruby_opts
12
+ t.ruby_opts += PROJ.test.opts
13
+ end
14
+
15
+ if HAVE_RCOV
16
+ desc 'Run rcov on the unit tests'
17
+ task :rcov => :clobber_rcov do
18
+ opts = PROJ.rcov.opts.dup << '-o' << PROJ.rcov.dir
19
+ opts = opts.join(' ')
20
+ files = if test(?f, PROJ.test.file) then [PROJ.test.file]
21
+ else PROJ.test.files end
22
+ files = files.join(' ')
23
+ sh "#{RCOV} #{files} #{opts}"
24
+ end
25
+
26
+ task :clobber_rcov do
27
+ rm_r 'coverage' rescue nil
28
+ end
29
+ end
30
+
31
+ end # namespace :test
32
+
33
+ desc 'Alias to test:run'
34
+ task :test => 'test:run'
35
+
36
+ task :clobber => 'test:clobber_rcov' if HAVE_RCOV
37
+
38
+ end
39
+
40
+ # EOF
data/test/all_tests.rb ADDED
@@ -0,0 +1,23 @@
1
+ %{
2
+ test_flags.rb
3
+ test_basic.rb
4
+ test_basic.rb
5
+ test_exact.rb
6
+ test_round.rb
7
+ test_multithreading.rb
8
+ test_comparisons.rb
9
+ test_coercion.rb
10
+ test_to_int.rb
11
+ test_to_rf.rb
12
+ test_define_conversions.rb
13
+ test_odd_even.rb
14
+ test_odd_epsilon.rb
15
+ test_ulp.rb
16
+ test_bin.rb
17
+ test_binfloat_conversion.rb
18
+ test_bin_arithmetic.rb
19
+ test_num_constructor.rb
20
+ }.each do |tst|
21
+ require File.expand_path(File.join(File.dirname(__FILE__), tst))
22
+ end
23
+
data/test/helper.rb ADDED
@@ -0,0 +1,101 @@
1
+ require 'test/unit'
2
+ require File.expand_path(File.join(File.dirname(__FILE__),'/../lib/flt'))
3
+ require 'enumerator'
4
+ include Flt
5
+
6
+ def initialize_context
7
+ DecNum.context = DecNum::ExtendedContext
8
+ BinNum.context = BinNum::ExtendedContext
9
+ end
10
+
11
+ def float_emulation_context
12
+ raise "BinNum tests require that Float is binary" unless Float::RADIX==2
13
+ BinNum.context = BinNum::FloatContext
14
+ BinNum.context.clamp = false
15
+ BinNum.context.traps.clear!
16
+ BinNum.context.flags.clear!
17
+ #
18
+ # BinNum.context.precision = Float::MANT_DIG
19
+ # BinNum.context.emin = Float::MIN_EXP-1
20
+ # BinNum.context.emax = Float::MAX_EXP-1
21
+ # BinNum.context.rounding = :half_even
22
+ end
23
+
24
+ def random_integer(min, max)
25
+ n = max - min + 1
26
+ rand(n) + min
27
+ end
28
+
29
+ def random_float
30
+ random_num Float
31
+ end
32
+
33
+ def random_bin_num
34
+ random_num BinNum
35
+ end
36
+
37
+ def random_dec_num
38
+ random_num DecNum
39
+ end
40
+
41
+ def random_num(num_class)
42
+ context = num_class.context
43
+ if rand(20)==0
44
+ # generate 5% of subnormals
45
+ f = rand(context.radix**(context.precision-1))
46
+ e = context.etiny
47
+ elsif rand(20)==0
48
+ # and some singular values too
49
+ if rand(1) == 0
50
+ f = context.radix**context.precision - 1
51
+ f -= rand(3)
52
+ else
53
+ f = context.radix**(context.precision - 1)
54
+ f += rand(3)
55
+ end
56
+ e = random_integer(context.etiny, context.etop)
57
+ else
58
+ f = rand(context.radix**context.precision)
59
+ e = random_integer(context.etiny, context.etop)
60
+ end
61
+ f = -f if rand(1)==0
62
+ context.Num(f, e)
63
+ end
64
+
65
+ def special_nums(num_class)
66
+ context = num_class.context
67
+ [context.nan, context.infinity, -context.infinity]
68
+ end
69
+
70
+ def singular_nums(num_class)
71
+ context = num_class.context
72
+ nums = [context.zero(-1), context.zero(+1), context.minimum_nonzero, -context.minimum_nonzero,
73
+ context.next_plus(context.minimum_nonzero), -context.next_plus(context.minimum_nonzero),
74
+ context.next_minus(context.maximum_subnormal), -context.next_minus(context.maximum_subnormal),
75
+ context.maximum_subnormal, -context.maximum_subnormal,
76
+ context.minimum_normal, -context.minimum_normal,
77
+ context.next_plus(context.minimum_normal), -context.next_plus(context.minimum_normal),
78
+ context.next_minus(context.maximum_finite), -context.next_minus(context.maximum_finite),
79
+ context.maximum_finite, -context.maximum_finite]
80
+ xs = [1,3,5]
81
+ xs += [context.radix, context.radix**2, context.radix**5, context.radix**10]
82
+ xs += [10,100,100000,10000000000] if context.radix!=10
83
+ xs += [2,4,32,1024] if context.radix!=2
84
+ nums += xs.map{|x| n = context.Num(x); [n,-n,context.next_minus(n),-context.next_minus(n),
85
+ context.next_plus(n),-context.next_plus(n)] }.flatten
86
+ nums
87
+ end
88
+
89
+ # this may be handy for problem reporting
90
+ def float_split(x)
91
+ s,e = Math.frexp(x)
92
+ [Math.ldexp(s,Float::MANT_DIG).to_i,e-Float::MANT_DIG]
93
+ end
94
+
95
+ def each_pair(array, &blk)
96
+ if RUBY_VERSION>="1.9"
97
+ array.each_slice(2,&blk)
98
+ else
99
+ array.enum_slice(2,&blk)
100
+ end
101
+ end
data/test/reader.rb ADDED
@@ -0,0 +1,68 @@
1
+ # Reader tests are lengthy and are not executed by default
2
+ # Must be explicitely executed, e.g. with
3
+ # rake test TEST=test/reader.rb
4
+
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
6
+
7
+ class TestReader < Test::Unit::TestCase
8
+
9
+
10
+ def setup
11
+ initialize_context
12
+ end
13
+
14
+ def test_algorithms_coherence
15
+ srand 1023022
16
+ data = []
17
+ DecNum.context(:precision=>15, :elimit=>90) do
18
+ data += [DecNum('1.448997445238699'), DecNum('1E23'),DecNum('-6.22320623338259E+16'),
19
+ DecNum('-3.83501075447972E-10'), DecNum('1.448997445238699')]
20
+ data += %w{
21
+ 1E23
22
+ 1.448997445238699
23
+ -6.22320623338259E+16
24
+ -3.83501075447972E-10
25
+ 1.448997445238699
26
+ 1.23E-30
27
+ 1.23456789E-20
28
+ 1.23456789E-30
29
+ 1.234567890123456789
30
+ 0.9999999999999995559107901499
31
+ 0.9999999999999996114219413812
32
+ 0.9999999999999996669330926125
33
+ 0.9999999999999997224442438437
34
+ 0.9999999999999997779553950750
35
+ 0.9999999999999998334665463062
36
+ 0.9999999999999998889776975375
37
+ 0.9999999999999999444888487687
38
+ 1
39
+ 1.000000000000000111022302463
40
+ 1.000000000000000222044604925
41
+ 1.000000000000000333066907388
42
+ 1.000000000000000444089209850
43
+ 1.000000000000000555111512313
44
+ 1.000000000000000666133814775
45
+ 1.000000000000000777156117238
46
+ 1.000000000000000888178419700
47
+ }.map{ |num| DecNum(num) }
48
+ data += Array.new(10000){random_num(DecNum)}
49
+ end
50
+ algs = [:M, :R, :A]
51
+ readers = algs.map{|alg| Flt::Support::Reader.new(:algorithm=>alg)}
52
+ [:half_even, :half_up, :half_down, :down, :up, :ceiling, :floor].each do |rounding|
53
+ data.each do |x|
54
+ s,f,e = x.split
55
+ b = x.num_class.radix
56
+ results = readers.map{|reader|
57
+ reader.read(BinNum.context, rounding, s, f, e, b)
58
+ }
59
+ (1...results.size).each do |i|
60
+ assert_equal results.first, results[i], "Read #{x} Alg. #{algs.first} (#{results.first}) != Alg. #{algs[i]} (#{results[i]})"
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,396 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ def exp(x,c=nil)
4
+ i, lasts, s, fact, num = 0, 0, 1, 1, 1
5
+ DecNum.local_context(c) do
6
+ # result context
7
+ DecNum.local_context do |context|
8
+ # working context
9
+ context.precision += 2
10
+ context.rounding = DecNum::ROUND_HALF_EVEN
11
+ while s != lasts
12
+ lasts = s
13
+ i += 1
14
+ fact *= i
15
+ num *= x
16
+ s += num / fact
17
+ end
18
+ end
19
+ +s
20
+ end
21
+ end
22
+
23
+ def exp1(x, c=nil)
24
+ return DecNum(BigDecimal("NaN")) if x.infinite? || x.nan?
25
+ y = nil
26
+ ext = 2
27
+ DecNum.local_context(c) do |context|
28
+ n = (context.precision += ext)
29
+
30
+ one = DecNum("1")
31
+ x1 = one
32
+ y = one
33
+ d = y
34
+ z = one
35
+ i = 0
36
+ while d.nonzero? && ((m = n - (y.fractional_exponent - d.fractional_exponent).abs) > 0)
37
+ m = ext if m < ext
38
+ x1 *= x
39
+ i += 1
40
+ z *= i
41
+
42
+ #d = x1.divide(z,:precision=>m)
43
+ context.precision = m
44
+ d = x1/z
45
+ context.precision = n
46
+
47
+ y += d
48
+ end
49
+ end
50
+ return +y
51
+ end
52
+
53
+ class TestBasic < Test::Unit::TestCase
54
+
55
+
56
+ def setup
57
+ initialize_context
58
+ end
59
+
60
+
61
+ def test_basic
62
+
63
+ DecNum.context.precision = 4
64
+ assert_equal 4, DecNum.context.precision
65
+ assert_equal DecNum("0.3333"), DecNum(1)/DecNum(3)
66
+ DecNum.context.precision = 10
67
+ assert_equal 10, DecNum.context.precision
68
+ assert_equal DecNum("0.3333333333"), DecNum(1)/DecNum(3)
69
+ DecNum.local_context {
70
+ assert_equal 10, DecNum.context.precision
71
+ DecNum.context.precision = 3
72
+ assert_equal 3, DecNum.context.precision
73
+ assert_equal DecNum("0.333"), DecNum(1)/DecNum(3)
74
+ }
75
+ assert_equal 10, DecNum.context.precision
76
+ assert_equal "0.3333333333", (DecNum(1)/DecNum(3)).to_s
77
+ assert_equal DecNum("0.3333333333"), DecNum(1)/DecNum(3)
78
+
79
+ DecNum.local_context(:precision=>4) {
80
+ assert_equal 4, DecNum.context.precision
81
+ }
82
+ assert_equal 10, DecNum.context.precision
83
+
84
+ DecNum.context(:precision=>4) {
85
+ assert_equal 4, DecNum.context.precision
86
+ }
87
+ assert_equal 10, DecNum.context.precision
88
+
89
+ DecNum.local_context(DecNum::BasicContext) {
90
+ assert_equal :half_up, DecNum.context.rounding
91
+ assert_equal 9, DecNum.context.precision
92
+ }
93
+ assert_equal :half_even, DecNum.context.rounding
94
+ assert_equal 10, DecNum.context.precision
95
+
96
+ DecNum.context(DecNum::BasicContext) {
97
+ assert_equal :half_up, DecNum.context.rounding
98
+ assert_equal 9, DecNum.context.precision
99
+ }
100
+ assert_equal :half_even, DecNum.context.rounding
101
+ assert_equal 10, DecNum.context.precision
102
+
103
+ DecNum.local_context(DecNum::BasicContext, :precision=>4) {
104
+ assert_equal :half_up, DecNum.context.rounding
105
+ assert_equal 4, DecNum.context.precision
106
+ }
107
+ assert_equal :half_even, DecNum.context.rounding
108
+ assert_equal 10, DecNum.context.precision
109
+
110
+ DecNum.context(DecNum::BasicContext, :precision=>4) {
111
+ assert_equal :half_up, DecNum.context.rounding
112
+ assert_equal 4, DecNum.context.precision
113
+ }
114
+ assert_equal :half_even, DecNum.context.rounding
115
+ assert_equal 10, DecNum.context.precision
116
+
117
+
118
+ assert_equal DecNum("0."+"3"*100), DecNum(1)./(DecNum(3),DecNum.Context(:precision=>100))
119
+ assert_equal 10, DecNum.context.precision
120
+ assert_equal DecNum("0.33"), DecNum(1).divide(DecNum(3),DecNum.Context(:precision=>2))
121
+ assert_equal DecNum("0.3333333333"), DecNum(1)/DecNum(3)
122
+
123
+ assert_equal DecNum("11.0"), DecNum(11).abs
124
+ assert_equal DecNum("11.0"), DecNum(-11).abs
125
+ assert_equal DecNum("-11.0"), -DecNum(11)
126
+
127
+ assert_equal [-11,0], DecNum("-11").to_int_scale
128
+
129
+ assert_equal [-110,-1], DecNum("-11.0").to_int_scale
130
+ assert_equal [-11,-1], DecNum("-1.1").to_int_scale
131
+ assert_equal [-110,0], DecNum("-110").to_int_scale
132
+ assert_equal [110,-1], DecNum("11.0").to_int_scale
133
+ assert_equal [11,-1], DecNum("1.1").to_int_scale
134
+ assert_equal [110,0], DecNum("110").to_int_scale
135
+
136
+ assert_equal [-11,0], DecNum("-11.0").reduce.to_int_scale
137
+ assert_equal [-11,-1], DecNum("-1.1").reduce.to_int_scale
138
+ assert_equal [-11,1], DecNum("-110").reduce.to_int_scale
139
+ assert_equal [11,0], DecNum("11.0").reduce.to_int_scale
140
+ assert_equal [11,-1], DecNum("1.1").reduce.to_int_scale
141
+ assert_equal [11,1], DecNum("110").reduce.to_int_scale
142
+
143
+
144
+ assert_equal DecNum('2.1'), DecNum('2.1').remainder(DecNum('3'))
145
+ assert_equal DecNum('-2.1'), DecNum('-2.1').remainder(DecNum('3'))
146
+ assert_equal DecNum('2.1'), DecNum('2.1').remainder(DecNum('-3'))
147
+ assert_equal DecNum('-2.1'), DecNum('-2.1').remainder(DecNum('-3'))
148
+ assert_equal DecNum('1'), DecNum('10').remainder(DecNum('3'))
149
+ assert_equal DecNum('-1'), DecNum('-10').remainder(DecNum('3'))
150
+ assert_equal DecNum('1'), DecNum('10').remainder(DecNum('-3'))
151
+ assert_equal DecNum('-1'), DecNum('-10').remainder(DecNum('-3'))
152
+ assert_equal DecNum('0.2'), DecNum('10.2').remainder(DecNum('1'))
153
+ assert_equal DecNum('0.1'), DecNum('10').remainder(DecNum('0.3'))
154
+ assert_equal DecNum('1.0'), DecNum('3.6').remainder(DecNum('1.3'))
155
+ assert_equal DecNum('2'), DecNum('2').remainder(DecNum('3'))
156
+ assert_equal DecNum('1'), DecNum('10').remainder(DecNum('3'))
157
+ assert_equal DecNum('.1'), DecNum('1').remainder(DecNum('0.3'))
158
+
159
+ assert_equal DecNum('0'), DecNum('2.1').divide_int(DecNum('3'))
160
+ assert_equal DecNum('0'), DecNum('-2.1').divide_int(DecNum('3'))
161
+ assert_equal DecNum('0'), DecNum('2.1').divide_int(DecNum('-3'))
162
+ assert_equal DecNum('0'), DecNum('-2.1').divide_int(DecNum('-3'))
163
+ assert_equal DecNum('3'), DecNum('10').divide_int(DecNum('3'))
164
+ assert_equal DecNum('-3'), DecNum('-10').divide_int(DecNum('3'))
165
+ assert_equal DecNum('-3'), DecNum('10').divide_int(DecNum('-3'))
166
+ assert_equal DecNum('3'), DecNum('-10').divide_int(DecNum('-3'))
167
+ assert_equal DecNum('10'), DecNum('10.2').divide_int(DecNum('1'))
168
+ assert_equal DecNum('33'), DecNum('10').divide_int(DecNum('0.3'))
169
+ assert_equal DecNum('2'), DecNum('3.6').divide_int(DecNum('1.3'))
170
+ assert_equal DecNum('0'), DecNum('2').divide_int(DecNum('3'))
171
+ assert_equal DecNum('3'), DecNum('10').divide_int(DecNum('3'))
172
+ assert_equal DecNum('3'), DecNum('1').divide_int(DecNum('0.3'))
173
+
174
+ assert_equal DecNum('2.1'), DecNum('2.1').modulo(DecNum('3'))
175
+ assert_equal DecNum('0.9'), DecNum('-2.1').modulo(DecNum('3'))
176
+ assert_equal DecNum('-0.9'), DecNum('2.1').modulo(DecNum('-3'))
177
+ assert_equal DecNum('-2.1'), DecNum('-2.1').modulo(DecNum('-3'))
178
+ assert_equal DecNum('1'), DecNum('10').modulo(DecNum('3'))
179
+ assert_equal DecNum('2'), DecNum('-10').modulo(DecNum('3'))
180
+ assert_equal DecNum('-2'), DecNum('10').modulo(DecNum('-3'))
181
+ assert_equal DecNum('-1'), DecNum('-10').modulo(DecNum('-3'))
182
+ assert_equal DecNum('0.2'), DecNum('10.2').modulo(DecNum('1'))
183
+ assert_equal DecNum('0.1'), DecNum('10').modulo(DecNum('0.3'))
184
+ assert_equal DecNum('1.0'), DecNum('3.6').modulo(DecNum('1.3'))
185
+ assert_equal DecNum('2'), DecNum('2').modulo(DecNum('3'))
186
+ assert_equal DecNum('1'), DecNum('10').modulo(DecNum('3'))
187
+ assert_equal DecNum('.1'), DecNum('1').modulo(DecNum('0.3'))
188
+
189
+ assert_equal DecNum('0'), DecNum('2.1').div(DecNum('3'))
190
+ assert_equal DecNum('-1'), DecNum('-2.1').div(DecNum('3'))
191
+ assert_equal DecNum('-1'), DecNum('2.1').div(DecNum('-3'))
192
+ assert_equal DecNum('0'), DecNum('-2.1').div(DecNum('-3'))
193
+ assert_equal DecNum('3'), DecNum('10').div(DecNum('3'))
194
+ assert_equal DecNum('-4'), DecNum('-10').div(DecNum('3'))
195
+ assert_equal DecNum('-4'), DecNum('10').div(DecNum('-3'))
196
+ assert_equal DecNum('3'), DecNum('-10').div(DecNum('-3'))
197
+ assert_equal DecNum('10'), DecNum('10.2').div(DecNum('1'))
198
+ assert_equal DecNum('33'), DecNum('10').div(DecNum('0.3'))
199
+ assert_equal DecNum('2'), DecNum('3.6').div(DecNum('1.3'))
200
+ assert_equal DecNum('0'), DecNum('2').div(DecNum('3'))
201
+ assert_equal DecNum('3'), DecNum('10').div(DecNum('3'))
202
+ assert_equal DecNum('3'), DecNum('1').div(DecNum('0.3'))
203
+
204
+ assert_equal DecNum('-0.9'), DecNum('2.1').remainder_near(DecNum('3'))
205
+ assert_equal DecNum('-2'), DecNum('10').remainder_near(DecNum('6'))
206
+ assert_equal DecNum('1'), DecNum('10').remainder_near(DecNum('3'))
207
+ assert_equal DecNum('-1'), DecNum('-10').remainder_near(DecNum('3'))
208
+ assert_equal DecNum('0.2'), DecNum('10.2').remainder_near(DecNum('1'))
209
+ assert_equal DecNum('0.1'), DecNum('10').remainder_near(DecNum('0.3'))
210
+ assert_equal DecNum('-0.3'), DecNum('3.6').remainder_near(DecNum('1.3'))
211
+
212
+
213
+ assert_equal 2, DecNum('123.4567').adjusted_exponent
214
+ assert_equal 2, DecNum('123.45670').adjusted_exponent
215
+ assert_equal 2, DecNum.context.scaleb(DecNum('1.2345670'),2).adjusted_exponent
216
+ assert_equal 2, DecNum.context.scaleb(DecNum('1.2345670'),DecNum('2')).adjusted_exponent
217
+ assert_equal DecNum(2), DecNum.context.logb(DecNum('123.4567'))
218
+ assert_equal DecNum(2), DecNum.context.logb(DecNum('123.45670'))
219
+ assert_equal 3, DecNum('123.4567').fractional_exponent
220
+ assert_equal 3, DecNum('123.45670').fractional_exponent
221
+
222
+ assert_equal(-7, DecNum.context.normalized_integral_exponent(DecNum('123.4567')))
223
+ assert_equal(1234567000, DecNum.context.normalized_integral_significand(DecNum('123.4567')))
224
+
225
+ assert_equal 7, DecNum('123.4567').number_of_digits
226
+ assert_equal 8, DecNum('123.45670').number_of_digits
227
+ assert_equal 7, DecNum('123.45670').reduce.number_of_digits
228
+
229
+ assert_equal 1234567, DecNum('123.4567').integral_significand
230
+ assert_equal 12345670, DecNum('123.45670').integral_significand
231
+ assert_equal 1234567, DecNum('123.45670').reduce.integral_significand
232
+
233
+ assert_equal 2, DecNum('-123.4567').adjusted_exponent
234
+ assert_equal 2, DecNum('-123.45670').adjusted_exponent
235
+ assert_equal 2, DecNum.context.scaleb(DecNum('-1.2345670'),2).adjusted_exponent
236
+ assert_equal 2, DecNum.context.scaleb(DecNum('-1.2345670'),DecNum('2')).adjusted_exponent
237
+ assert_equal DecNum(2), DecNum.context.logb(DecNum('-123.4567'))
238
+ assert_equal DecNum(2), DecNum.context.logb(DecNum('-123.45670'))
239
+ assert_equal 3, DecNum('-123.4567').fractional_exponent
240
+ assert_equal 3, DecNum('-123.45670').fractional_exponent
241
+
242
+ assert_equal(-7, DecNum.context.normalized_integral_exponent(DecNum('-123.4567')))
243
+ assert_equal(1234567000, DecNum.context.normalized_integral_significand(DecNum('-123.4567')))
244
+
245
+ assert_equal 7, DecNum('-123.4567').number_of_digits
246
+ # assert_equal 9, DecNum('123.45670').number_of_digits # not with BigDecimal
247
+ assert_equal 7, DecNum('-123.45670').reduce.number_of_digits
248
+
249
+ assert_equal(1234567, DecNum('-123.4567').integral_significand)
250
+ #assert_equal(12345670, DecNum('-123.45670').integral_significand) # not with BigDecimal
251
+ assert_equal(1234567, DecNum('-123.45670').reduce.integral_significand)
252
+
253
+ x = DecNum('123.4567')
254
+ assert_equal x, DecNum(x.integral_significand)*10**x.integral_exponent
255
+ assert_equal x, DecNum(DecNum.context.normalized_integral_significand(x))*10**DecNum.context.normalized_integral_exponent(x)
256
+
257
+ assert_equal x, DecNum.context.scaleb(x.integral_significand, x.integral_exponent)
258
+ assert_equal x, DecNum.context.scaleb(DecNum.context.normalized_integral_significand(x),DecNum.context.normalized_integral_exponent(x))
259
+
260
+ x = DecNum('-123.4567')
261
+ assert_equal x.abs, DecNum(x.integral_significand)*10**x.integral_exponent
262
+ assert_equal x.abs, DecNum(DecNum.context.normalized_integral_significand(x))*10**DecNum.context.normalized_integral_exponent(x)
263
+
264
+ assert_equal x.abs, DecNum.context.scaleb(x.integral_significand, x.integral_exponent)
265
+ assert_equal x.abs, DecNum.context.scaleb(DecNum.context.normalized_integral_significand(x),DecNum.context.normalized_integral_exponent(x))
266
+
267
+ DecNum.context.precision = 3
268
+ DecNum.context.rounding = :half_up
269
+ assert_equal DecNum("100"), (+DecNum('100.4'))
270
+ assert_equal DecNum("101"), (+DecNum('101.4'))
271
+ assert_equal DecNum("101"), (+DecNum('100.5'))
272
+ assert_equal DecNum("102"), (+DecNum('101.5'))
273
+ assert_equal DecNum("-101"), (+DecNum('-100.5'))
274
+ assert_equal DecNum("-102"), (+DecNum('-101.5'))
275
+ assert_equal DecNum("-100"), (+DecNum('-100.4'))
276
+ assert_equal DecNum("-101"), (+DecNum('-101.4'))
277
+ DecNum.context.rounding = :half_even
278
+ assert_equal DecNum("100"), (+DecNum('100.5'))
279
+ assert_equal DecNum("101"), (+DecNum('100.51'))
280
+ assert_equal DecNum("101"), (+DecNum('100.6'))
281
+ assert_equal DecNum("102"), (+DecNum('101.5'))
282
+ assert_equal DecNum("101"), (+DecNum('101.4'))
283
+ assert_equal DecNum("-100"), (+DecNum('-100.5'))
284
+ assert_equal DecNum("-102"), (+DecNum('-101.5'))
285
+ assert_equal DecNum("-101"), (+DecNum('-101.4'))
286
+ DecNum.context.rounding = :half_down
287
+ assert_equal DecNum("100"), (+DecNum('100.5'))
288
+ assert_equal DecNum("101"), (+DecNum('101.5'))
289
+ assert_equal DecNum("-100"), (+DecNum('-100.5'))
290
+ assert_equal DecNum("-101"), (+DecNum('-101.5'))
291
+ DecNum.context.rounding = :down
292
+ assert_equal DecNum("100"), (+DecNum('100.9'))
293
+ assert_equal DecNum("101"), (+DecNum('101.9'))
294
+ assert_equal DecNum("-100"), (+DecNum('-100.9'))
295
+ assert_equal DecNum("-101"), (+DecNum('-101.9'))
296
+ DecNum.context.rounding = :up
297
+ assert_equal DecNum("101"), (+DecNum('100.1'))
298
+ assert_equal DecNum("102"), (+DecNum('101.1'))
299
+ assert_equal DecNum("-101"), (+DecNum('-100.1'))
300
+ assert_equal DecNum("-102"), (+DecNum('-101.1'))
301
+ DecNum.context.rounding = :floor
302
+ assert_equal DecNum("100"), (+DecNum('100.9'))
303
+ assert_equal DecNum("101"), (+DecNum('101.9'))
304
+ assert_equal DecNum("-101"), (+DecNum('-100.9'))
305
+ assert_equal DecNum("-102"), (+DecNum('-101.9'))
306
+ DecNum.context.rounding = :ceiling
307
+ assert_equal DecNum("101"), (+DecNum('100.1'))
308
+ assert_equal DecNum("102"), (+DecNum('101.1'))
309
+ assert_equal DecNum("-100"), (+DecNum('-100.1'))
310
+ assert_equal DecNum("-101"), (+DecNum('-101.1'))
311
+
312
+ end
313
+
314
+ def test_exp
315
+ DecNum.context.precision = 100
316
+ DecNum.context.rounding = :half_even
317
+ e_100 = "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"
318
+ assert_equal e_100, exp(DecNum(1)).to_s
319
+ assert_equal DecNum(e_100), exp(DecNum(1))
320
+ assert_equal e_100, exp1(DecNum(1)).to_s
321
+ assert_equal DecNum(e_100), exp1(DecNum(1))
322
+ end
323
+
324
+ def test_special
325
+ nan = DecNum(0)/DecNum(0)
326
+ inf_pos = DecNum(1)/DecNum(0)
327
+ inf_neg = DecNum(-1)/DecNum(0)
328
+ zero_pos = DecNum(0)
329
+ zero_neg = DecNum('-0')
330
+ pos = DecNum(1)
331
+ neg = DecNum(-1)
332
+
333
+ assert nan.nan?
334
+ assert nan.special?
335
+ assert !nan.zero?
336
+ assert !nan.finite?
337
+ assert !nan.infinite?
338
+ assert inf_pos.infinite?
339
+ assert !inf_pos.finite?
340
+ assert !inf_pos.nan?
341
+ assert inf_pos.special?
342
+ assert inf_neg.infinite?
343
+ assert !inf_neg.finite?
344
+ assert !inf_neg.nan?
345
+ assert inf_neg.special?
346
+ assert zero_pos.finite?
347
+ assert zero_neg.finite?
348
+ assert zero_pos.zero?
349
+ assert zero_neg.zero?
350
+ assert !pos.zero?
351
+ assert !neg.zero?
352
+ assert pos.nonzero?
353
+ assert neg.nonzero?
354
+
355
+ #assert nan.sign.nil?
356
+ assert_equal(+1, inf_pos.sign)
357
+ assert_equal(-1, inf_neg.sign)
358
+ assert_equal(+1, zero_pos.sign)
359
+ assert_equal(-1, zero_neg.sign)
360
+ assert_equal(+1, pos.sign)
361
+ assert_equal(-1, neg.sign)
362
+ end
363
+
364
+ def test_context_parameters
365
+ #DecNum.context = DecNum.Context
366
+ DecNum.context.precision = 3
367
+ DecNum.context.rounding = :half_even
368
+ x = DecNum(1)
369
+ y = DecNum(3)
370
+ assert_equal DecNum('0.333'), x.divide(y)
371
+ assert_equal DecNum('0.3333'), x.divide(y, DecNum.Context(:precision=>4))
372
+ assert_equal DecNum('0.333'), x.divide(y)
373
+ assert_equal DecNum('0.33333'), x.divide(y, :precision=>5)
374
+ end
375
+
376
+ def test_integer
377
+
378
+ %w{ 0 0E10 0E-10 12.0 12 120E-1 12.1E10 }.each do |x|
379
+ assert DecNum(x).integral?, "DecNum('#{x}').integral?"
380
+ end
381
+
382
+ [12, Rational(6,2)].each do |x|
383
+ assert DecNum(x).integral?, "DecNum(#{x}).integral?"
384
+ end
385
+
386
+ %w{ NaN Inf 12.1 121E-1 }.each do |x|
387
+ assert !DecNum(x).integral?, "!DecNum('#{x}').integral?"
388
+ end
389
+
390
+ [ Rational(121,10) ].each do |x|
391
+ assert !DecNum(x).integral?, "!DecNum(#{x}).integral?"
392
+ end
393
+
394
+ end
395
+
396
+ end