flt 1.0.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.
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