rubysl-bigdecimal 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/ext/rubysl/bigdecimal/bigdecimal.c +4760 -0
- data/ext/rubysl/bigdecimal/bigdecimal.h +220 -0
- data/ext/rubysl/bigdecimal/extconf.rb +6 -0
- data/lib/bigdecimal.rb +1 -0
- data/lib/bigdecimal/README +60 -0
- data/lib/bigdecimal/bigdecimal_en.html +796 -0
- data/lib/bigdecimal/bigdecimal_ja.html +799 -0
- data/lib/bigdecimal/jacobian.rb +85 -0
- data/lib/bigdecimal/ludcmp.rb +84 -0
- data/lib/bigdecimal/math.rb +235 -0
- data/lib/bigdecimal/newton.rb +77 -0
- data/lib/bigdecimal/sample/linear.rb +71 -0
- data/lib/bigdecimal/sample/nlsolve.rb +38 -0
- data/lib/bigdecimal/sample/pi.rb +20 -0
- data/lib/bigdecimal/util.rb +65 -0
- data/lib/rubysl/bigdecimal.rb +2 -0
- data/lib/rubysl/bigdecimal/version.rb +5 -0
- data/rubysl-bigdecimal.gemspec +24 -0
- data/spec/abs_spec.rb +49 -0
- data/spec/add_spec.rb +178 -0
- data/spec/case_compare_spec.rb +6 -0
- data/spec/ceil_spec.rb +122 -0
- data/spec/coerce_spec.rb +25 -0
- data/spec/comparison_spec.rb +80 -0
- data/spec/div_spec.rb +143 -0
- data/spec/divide_spec.rb +6 -0
- data/spec/divmod_spec.rb +233 -0
- data/spec/double_fig_spec.rb +8 -0
- data/spec/eql_spec.rb +5 -0
- data/spec/equal_value_spec.rb +6 -0
- data/spec/exponent_spec.rb +37 -0
- data/spec/finite_spec.rb +34 -0
- data/spec/fix_spec.rb +56 -0
- data/spec/fixtures/classes.rb +17 -0
- data/spec/floor_spec.rb +109 -0
- data/spec/frac_spec.rb +47 -0
- data/spec/gt_spec.rb +86 -0
- data/spec/gte_spec.rb +90 -0
- data/spec/induced_from_spec.rb +36 -0
- data/spec/infinite_spec.rb +31 -0
- data/spec/inspect_spec.rb +40 -0
- data/spec/limit_spec.rb +29 -0
- data/spec/lt_spec.rb +84 -0
- data/spec/lte_spec.rb +90 -0
- data/spec/minus_spec.rb +57 -0
- data/spec/mode_spec.rb +64 -0
- data/spec/modulo_spec.rb +11 -0
- data/spec/mult_spec.rb +23 -0
- data/spec/multiply_spec.rb +25 -0
- data/spec/nan_spec.rb +22 -0
- data/spec/new_spec.rb +120 -0
- data/spec/nonzero_spec.rb +28 -0
- data/spec/plus_spec.rb +49 -0
- data/spec/power_spec.rb +5 -0
- data/spec/precs_spec.rb +48 -0
- data/spec/quo_spec.rb +12 -0
- data/spec/remainder_spec.rb +83 -0
- data/spec/round_spec.rb +193 -0
- data/spec/shared/eql.rb +65 -0
- data/spec/shared/modulo.rb +146 -0
- data/spec/shared/mult.rb +97 -0
- data/spec/shared/power.rb +83 -0
- data/spec/shared/quo.rb +59 -0
- data/spec/shared/to_int.rb +27 -0
- data/spec/sign_spec.rb +46 -0
- data/spec/split_spec.rb +87 -0
- data/spec/sqrt_spec.rb +111 -0
- data/spec/sub_spec.rb +52 -0
- data/spec/to_f_spec.rb +54 -0
- data/spec/to_i_spec.rb +6 -0
- data/spec/to_int_spec.rb +7 -0
- data/spec/to_s_spec.rb +71 -0
- data/spec/truncate_spec.rb +100 -0
- data/spec/uminus_spec.rb +57 -0
- data/spec/uplus_spec.rb +19 -0
- data/spec/ver_spec.rb +10 -0
- data/spec/zero_spec.rb +27 -0
- metadata +243 -0
data/spec/mult_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../shared/mult', __FILE__)
|
2
|
+
require 'bigdecimal'
|
3
|
+
|
4
|
+
describe "BigDecimal#mult" do
|
5
|
+
it_behaves_like :bigdecimal_mult, :mult, [10]
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "BigDecimal#mult" do
|
9
|
+
before :each do
|
10
|
+
@one = BigDecimal "1"
|
11
|
+
@e3_minus = BigDecimal "3E-20001"
|
12
|
+
@e = BigDecimal "1.00000000000000000000123456789"
|
13
|
+
@tolerance = @e.sub @one, 1000
|
14
|
+
@tolerance2 = BigDecimal "30001E-20005"
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
it "multiply self with other with (optional) precision" do
|
19
|
+
@e.mult(@one, 1).should be_close(@one, @tolerance)
|
20
|
+
@e3_minus.mult(@one, 1).should be_close(0, @tolerance2)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path('../shared/mult', __FILE__)
|
2
|
+
require 'bigdecimal'
|
3
|
+
|
4
|
+
describe "BigDecimal#*" do
|
5
|
+
it_behaves_like :bigdecimal_mult, :*, []
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "BigDecimal#*" do
|
9
|
+
before(:each) do
|
10
|
+
@e3_minus = BigDecimal("3E-20001")
|
11
|
+
@e3_plus = BigDecimal("3E20001")
|
12
|
+
@e = BigDecimal("1.00000000000000000000123456789")
|
13
|
+
@one = BigDecimal("1")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "multiply self with other" do
|
17
|
+
(@one * @one).should == @one
|
18
|
+
(@e3_minus * @e3_plus).should == BigDecimal("9")
|
19
|
+
# Can't do this till we implement **
|
20
|
+
# (@e3_minus * @e3_minus).should == @e3_minus ** 2
|
21
|
+
# So let's rewrite it as:
|
22
|
+
(@e3_minus * @e3_minus).should == BigDecimal("9E-40002")
|
23
|
+
(@e * @one).should == @e
|
24
|
+
end
|
25
|
+
end
|
data/spec/nan_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#nan?" do
|
4
|
+
|
5
|
+
it "returns true if self is not a number" do
|
6
|
+
BigDecimal("NaN").nan?.should == true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns false if self is not a NaN" do
|
10
|
+
BigDecimal("Infinity").nan?.should == false
|
11
|
+
BigDecimal("-Infinity").nan?.should == false
|
12
|
+
BigDecimal("0").nan?.should == false
|
13
|
+
BigDecimal("+0").nan?.should == false
|
14
|
+
BigDecimal("-0").nan?.should == false
|
15
|
+
BigDecimal("2E40001").nan?.should == false
|
16
|
+
BigDecimal("3E-20001").nan?.should == false
|
17
|
+
BigDecimal("0E-200000000").nan?.should == false
|
18
|
+
BigDecimal("0E200000000000").nan?.should == false
|
19
|
+
BigDecimal("0.000000000000000000000000").nan?.should == false
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/spec/new_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal.new" do
|
4
|
+
|
5
|
+
it "creates a new object of class BigDecimal" do
|
6
|
+
BigDecimal.new("3.14159").should be_kind_of(BigDecimal)
|
7
|
+
(0..9).each {|i|
|
8
|
+
BigDecimal.new("1#{i}").should == 10 + i
|
9
|
+
BigDecimal.new("-1#{i}").should == -10 - i
|
10
|
+
BigDecimal.new("1E#{i}").should == 10**i
|
11
|
+
BigDecimal.new("1000000E-#{i}").should == 10**(6-i)
|
12
|
+
}
|
13
|
+
(1..9).each {|i|
|
14
|
+
BigDecimal.new("100.#{i}").to_s.should == "0.100#{i}E3"
|
15
|
+
BigDecimal.new("-100.#{i}").to_s.should == "-0.100#{i}E3"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
ruby_bug "1589", "1.8.6.368" do
|
20
|
+
ruby_version_is '' ... '1.9.3' do
|
21
|
+
platform_is :wordsize => 32 do
|
22
|
+
it "doesn't segfault when using a very large string to build the number" do
|
23
|
+
BigDecimal.new("1" + "0"*10000000)._dump.should == "10000008:0.1E10000001"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
platform_is :wordsize => 64 do
|
28
|
+
it "doesn't segfault when using a very large string to build the number" do
|
29
|
+
BigDecimal.new("1" + "0"*10000000)._dump.should == "10000017:0.1E10000001"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
ruby_version_is '1.9.3' do
|
35
|
+
it "doesn't segfault when using a very large string to build the number" do
|
36
|
+
BigDecimal.new("1" + "0"*10000000)._dump.should == "10000017:0.1E10000001"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "Number of significant digits >= given precision" do
|
42
|
+
pi_string = "3.1415923"
|
43
|
+
BigDecimal.new("3.1415923", 10).precs[1].should >= 10
|
44
|
+
end
|
45
|
+
|
46
|
+
it "determines precision from initial value" do
|
47
|
+
pi_string = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593014782083152134043"
|
48
|
+
BigDecimal.new(pi_string).precs[1].should >= pi_string.size-1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "ignores leading whitespace" do
|
52
|
+
BigDecimal.new(" \t\n \r1234").should == BigDecimal.new("1234")
|
53
|
+
BigDecimal.new(" \t\n \rNaN \n").nan?.should == true
|
54
|
+
BigDecimal.new(" \t\n \rInfinity \n").infinite?.should == 1
|
55
|
+
BigDecimal.new(" \t\n \r-Infinity \n").infinite?.should == -1
|
56
|
+
BigDecimal.new(" \t\n \r-\t\t\tInfinity \n").should == 0.0
|
57
|
+
end
|
58
|
+
|
59
|
+
it "ignores trailing garbage" do
|
60
|
+
BigDecimal.new("123E45ruby").should == BigDecimal.new("123E45")
|
61
|
+
BigDecimal.new("123x45").should == BigDecimal.new("123")
|
62
|
+
BigDecimal.new("123.4%E5").should == BigDecimal.new("123.4")
|
63
|
+
BigDecimal.new("1E2E3E4E5E").should == BigDecimal.new("100")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "treats invalid strings as 0.0" do
|
67
|
+
BigDecimal.new("ruby").should == BigDecimal.new("0.0")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "allows omitting the integer part" do
|
71
|
+
BigDecimal.new(".123").should == BigDecimal.new("0.123")
|
72
|
+
ruby_version_is "1.8.6.5000" do
|
73
|
+
BigDecimal.new("-.123").should == BigDecimal.new("-0.123")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "allows for underscores in all parts" do
|
78
|
+
reference = BigDecimal.new("12345.67E89")
|
79
|
+
|
80
|
+
BigDecimal.new("12_345.67E89").should == reference
|
81
|
+
BigDecimal.new("1_2_3_4_5_._6____7_E89").should == reference
|
82
|
+
BigDecimal.new("12345_.67E_8__9_").should == reference
|
83
|
+
end
|
84
|
+
|
85
|
+
it "accepts NaN and [+-]Infinity" do
|
86
|
+
BigDecimal.new("NaN").nan?.should == true
|
87
|
+
|
88
|
+
pos_inf = BigDecimal.new("Infinity")
|
89
|
+
pos_inf.finite?.should == false
|
90
|
+
pos_inf.should > 0
|
91
|
+
pos_inf.should == BigDecimal.new("+Infinity")
|
92
|
+
|
93
|
+
neg_inf = BigDecimal.new("-Infinity")
|
94
|
+
neg_inf.finite?.should == false
|
95
|
+
neg_inf.should < 0
|
96
|
+
end
|
97
|
+
|
98
|
+
it "allows for [eEdD] as exponent separator" do
|
99
|
+
reference = BigDecimal.new("12345.67E89")
|
100
|
+
|
101
|
+
BigDecimal.new("12345.67e89").should == reference
|
102
|
+
BigDecimal.new("12345.67E89").should == reference
|
103
|
+
BigDecimal.new("12345.67d89").should == reference
|
104
|
+
BigDecimal.new("12345.67D89").should == reference
|
105
|
+
end
|
106
|
+
|
107
|
+
it "allows for varying signs" do
|
108
|
+
reference = BigDecimal.new("123.456E1")
|
109
|
+
|
110
|
+
BigDecimal.new("+123.456E1").should == reference
|
111
|
+
BigDecimal.new("-123.456E1").should == -reference
|
112
|
+
BigDecimal.new("123.456E+1").should == reference
|
113
|
+
BigDecimal.new("12345.6E-1").should == reference
|
114
|
+
BigDecimal.new("+123.456E+1").should == reference
|
115
|
+
BigDecimal.new("+12345.6E-1").should == reference
|
116
|
+
BigDecimal.new("-123.456E+1").should == -reference
|
117
|
+
BigDecimal.new("-12345.6E-1").should == -reference
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#nonzero?" do
|
4
|
+
|
5
|
+
it "returns self if self doesn't equal zero" do
|
6
|
+
# documentation says, it returns true. (04/10/08)
|
7
|
+
e2_plus = BigDecimal("2E40001")
|
8
|
+
e3_minus = BigDecimal("3E-20001")
|
9
|
+
infinity = BigDecimal("Infinity")
|
10
|
+
infinity_minus = BigDecimal("-Infinity")
|
11
|
+
nan = BigDecimal("NaN")
|
12
|
+
infinity.nonzero?.should equal(infinity)
|
13
|
+
infinity_minus.nonzero?.should equal(infinity_minus)
|
14
|
+
nan.nonzero?.should equal(nan)
|
15
|
+
e3_minus.nonzero?.should equal(e3_minus)
|
16
|
+
e2_plus.nonzero?.should equal(e2_plus)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns nil otherwise" do
|
20
|
+
# documentation states, it should return false. (04/10/08)
|
21
|
+
really_small_zero = BigDecimal("0E-200000000")
|
22
|
+
really_big_zero = BigDecimal("0E200000000000")
|
23
|
+
really_small_zero.nonzero?.should == nil
|
24
|
+
really_big_zero.nonzero?.should == nil
|
25
|
+
BigDecimal("0.000000000000000000000000").nonzero?.should == nil
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/spec/plus_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#+" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@one = BigDecimal("1")
|
7
|
+
@zero = BigDecimal("0")
|
8
|
+
@two = BigDecimal("2")
|
9
|
+
@three = BigDecimal("3")
|
10
|
+
@ten = BigDecimal("10")
|
11
|
+
@eleven = BigDecimal("11")
|
12
|
+
@nan = BigDecimal("NaN")
|
13
|
+
@infinity = BigDecimal("Infinity")
|
14
|
+
@infinity_minus = BigDecimal("-Infinity")
|
15
|
+
@one_minus = BigDecimal("-1")
|
16
|
+
@frac_1 = BigDecimal("1E-99999")
|
17
|
+
@frac_2 = BigDecimal("0.9E-99999")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a + b" do
|
21
|
+
|
22
|
+
(@two + @one).should == @three
|
23
|
+
(@one + @two).should == @three
|
24
|
+
(@one + @one_minus).should == @zero
|
25
|
+
(@zero + @one).should == @one
|
26
|
+
(@ten + @one).should == @eleven
|
27
|
+
(@frac_1 + @frac_2).should == BigDecimal("1.9E-99999")
|
28
|
+
(@frac_2 + @frac_1).should == BigDecimal("1.9E-99999")
|
29
|
+
(@frac_1 + @frac_1).should == BigDecimal("2E-99999")
|
30
|
+
# can't do it this way because * isn't implemented yet
|
31
|
+
# (@frac_1 + @frac_1).should == 2 * @frac_1
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns NaN if NaN is involved" do
|
35
|
+
(@one + @nan).nan?.should == true
|
36
|
+
(@nan + @one).nan?.should == true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns Infinity or -Infinity if these are involved" do
|
40
|
+
(@zero + @infinity).should == @infinity
|
41
|
+
(@frac_2 + @infinity).should == @infinity
|
42
|
+
(@two + @infinity_minus).should == @infinity_minus
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns NaN if Infinity + (- Infinity)" do
|
46
|
+
(@infinity + @infinity_minus).nan?.should == true
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/spec/power_spec.rb
ADDED
data/spec/precs_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#precs" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@infinity = BigDecimal("Infinity")
|
7
|
+
@infinity_neg = BigDecimal("-Infinity")
|
8
|
+
@nan = BigDecimal("NaN")
|
9
|
+
@zero = BigDecimal("0")
|
10
|
+
@zero_neg = BigDecimal("-0")
|
11
|
+
|
12
|
+
@arr = [BigDecimal("2E40001"), BigDecimal("3E-20001"),\
|
13
|
+
@infinity, @infinity_neg, @nan, @zero, @zero_neg]
|
14
|
+
@precision = BigDecimal::BASE.to_s.length - 1
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns array of two values" do
|
18
|
+
@arr.each do |x|
|
19
|
+
x.precs.kind_of?(Array).should == true
|
20
|
+
x.precs.size.should == 2
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns Integers as array values" do
|
25
|
+
@arr.each do |x|
|
26
|
+
x.precs[0].kind_of?(Integer).should == true
|
27
|
+
x.precs[1].kind_of?(Integer).should == true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns the current value of significant digits as the first value" do
|
32
|
+
BigDecimal("3.14159").precs[0].should >= 6
|
33
|
+
BigDecimal('1').precs[0].should == BigDecimal('1' + '0' * 100).precs[0]
|
34
|
+
[@infinity, @infinity_neg, @nan, @zero, @zero_neg].each do |value|
|
35
|
+
value.precs[0].should <= @precision
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns the maximum number of significant digits as the second value" do
|
40
|
+
BigDecimal("3.14159").precs[1].should >= 6
|
41
|
+
BigDecimal('1').precs[1].should >= 1
|
42
|
+
BigDecimal('1' + '0' * 100).precs[1] >= 101
|
43
|
+
[@infinity, @infinity_neg, @nan, @zero, @zero_neg].each do |value|
|
44
|
+
value.precs[1].should >= 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/spec/quo_spec.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path('../shared/quo', __FILE__)
|
2
|
+
require 'bigdecimal'
|
3
|
+
|
4
|
+
describe "BigDecimal#quo" do
|
5
|
+
it_behaves_like :bigdecimal_quo, :quo, []
|
6
|
+
|
7
|
+
it "returns NaN if NaN is involved" do
|
8
|
+
BigDecimal("1").quo(BigDecimal("NaN")).nan?.should == true
|
9
|
+
BigDecimal("NaN").quo(BigDecimal("1")).nan?.should == true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#remainder" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@zero = BigDecimal("0")
|
7
|
+
@one = BigDecimal("0")
|
8
|
+
@mixed = BigDecimal("1.23456789")
|
9
|
+
@pos_int = BigDecimal("2E5555")
|
10
|
+
@neg_int = BigDecimal("-2E5555")
|
11
|
+
@pos_frac = BigDecimal("2E-9999")
|
12
|
+
@neg_frac = BigDecimal("-2E-9999")
|
13
|
+
@nan = BigDecimal("NaN")
|
14
|
+
@infinity = BigDecimal("Infinity")
|
15
|
+
@infinity_minus = BigDecimal("-Infinity")
|
16
|
+
@one_minus = BigDecimal("-1")
|
17
|
+
@frac_1 = BigDecimal("1E-99999")
|
18
|
+
@frac_2 = BigDecimal("0.9E-99999")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "it equals modulo, if both values are of same sign" do
|
22
|
+
BigDecimal('1234567890123456789012345679').remainder(BigDecimal('1')).should == @zero
|
23
|
+
BigDecimal('123456789').remainder(BigDecimal('333333333333333333333333333E-50')).should == BigDecimal('0.12233333333333333333345679E-24')
|
24
|
+
|
25
|
+
@mixed.remainder(@pos_frac).should == @mixed % @pos_frac
|
26
|
+
@pos_int.remainder(@pos_frac).should == @pos_int % @pos_frac
|
27
|
+
@neg_frac.remainder(@neg_int).should == @neg_frac % @neg_int
|
28
|
+
@neg_int.remainder(@neg_frac).should == @neg_int % @neg_frac
|
29
|
+
end
|
30
|
+
|
31
|
+
it "means self-arg*(self/arg).truncate" do
|
32
|
+
@mixed.remainder(@neg_frac).should == @mixed - @neg_frac * (@mixed / @neg_frac).truncate
|
33
|
+
@pos_int.remainder(@neg_frac).should == @pos_int - @neg_frac * (@pos_int / @neg_frac).truncate
|
34
|
+
@neg_frac.remainder(@pos_int).should == @neg_frac - @pos_int * (@neg_frac / @pos_int).truncate
|
35
|
+
@neg_int.remainder(@pos_frac).should == @neg_int - @pos_frac * (@neg_int / @pos_frac).truncate
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns NaN used with zero" do
|
39
|
+
@mixed.remainder(@zero).nan?.should == true
|
40
|
+
@zero.remainder(@zero).nan?.should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns zero if used on zero" do
|
44
|
+
@zero.remainder(@mixed).should == @zero
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns NaN if NaN is involved" do
|
48
|
+
@nan.remainder(@nan).nan?.should == true
|
49
|
+
@nan.remainder(@one).nan?.should == true
|
50
|
+
@one.remainder(@nan).nan?.should == true
|
51
|
+
@infinity.remainder(@nan).nan?.should == true
|
52
|
+
@nan.remainder(@infinity).nan?.should == true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns NaN if Infinity is involved" do
|
56
|
+
@infinity.remainder(@infinity).nan?.should == true
|
57
|
+
@infinity.remainder(@one).nan?.should == true
|
58
|
+
@infinity.remainder(@mixed).nan?.should == true
|
59
|
+
@infinity.remainder(@one_minus).nan?.should == true
|
60
|
+
@infinity.remainder(@frac_1).nan?.should == true
|
61
|
+
@one.remainder(@infinity).nan?.should == true
|
62
|
+
|
63
|
+
@infinity_minus.remainder(@infinity_minus).nan?.should == true
|
64
|
+
@infinity_minus.remainder(@one).nan?.should == true
|
65
|
+
@one.remainder(@infinity_minus).nan?.should == true
|
66
|
+
@frac_2.remainder(@infinity_minus).nan?.should == true
|
67
|
+
|
68
|
+
@infinity.remainder(@infinity_minus).nan?.should == true
|
69
|
+
@infinity_minus.remainder(@infinity).nan?.should == true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "coerces arguments to BigDecimal if possible" do
|
73
|
+
@one.remainder(2).should == @one
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
it "raises TypeError if the argument cannot be coerced to BigDecimal" do
|
78
|
+
lambda {
|
79
|
+
@one.remainder('2')
|
80
|
+
}.should raise_error(TypeError)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
data/spec/round_spec.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
describe "BigDecimal#round" do
|
4
|
+
before :each do
|
5
|
+
@one = BigDecimal("1")
|
6
|
+
@two = BigDecimal("2")
|
7
|
+
@three = BigDecimal("3")
|
8
|
+
|
9
|
+
@neg_one = BigDecimal("-1")
|
10
|
+
@neg_two = BigDecimal("-2")
|
11
|
+
@neg_three = BigDecimal("-3")
|
12
|
+
|
13
|
+
@p1_50 = BigDecimal("1.50")
|
14
|
+
@p1_51 = BigDecimal("1.51")
|
15
|
+
@p1_49 = BigDecimal("1.49")
|
16
|
+
@n1_50 = BigDecimal("-1.50")
|
17
|
+
@n1_51 = BigDecimal("-1.51")
|
18
|
+
@n1_49 = BigDecimal("-1.49")
|
19
|
+
|
20
|
+
@p2_50 = BigDecimal("2.50")
|
21
|
+
@p2_51 = BigDecimal("2.51")
|
22
|
+
@p2_49 = BigDecimal("2.49")
|
23
|
+
@n2_50 = BigDecimal("-2.50")
|
24
|
+
@n2_51 = BigDecimal("-2.51")
|
25
|
+
@n2_49 = BigDecimal("-2.49")
|
26
|
+
end
|
27
|
+
|
28
|
+
after :each do
|
29
|
+
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "uses default rounding method unless given" do
|
33
|
+
@p1_50.round(0).should == @two
|
34
|
+
@p1_51.round(0).should == @two
|
35
|
+
@p1_49.round(0).should == @one
|
36
|
+
@n1_50.round(0).should == @neg_two
|
37
|
+
@n1_51.round(0).should == @neg_two
|
38
|
+
@n1_49.round(0).should == @neg_one
|
39
|
+
|
40
|
+
@p2_50.round(0).should == @three
|
41
|
+
@p2_51.round(0).should == @three
|
42
|
+
@p2_49.round(0).should == @two
|
43
|
+
@n2_50.round(0).should == @neg_three
|
44
|
+
@n2_51.round(0).should == @neg_three
|
45
|
+
@n2_49.round(0).should == @neg_two
|
46
|
+
|
47
|
+
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
|
48
|
+
|
49
|
+
@p1_50.round(0).should == @one
|
50
|
+
@p1_51.round(0).should == @one
|
51
|
+
@p1_49.round(0).should == @one
|
52
|
+
@n1_50.round(0).should == @neg_one
|
53
|
+
@n1_51.round(0).should == @neg_one
|
54
|
+
@n1_49.round(0).should == @neg_one
|
55
|
+
|
56
|
+
@p2_50.round(0).should == @two
|
57
|
+
@p2_51.round(0).should == @two
|
58
|
+
@p2_49.round(0).should == @two
|
59
|
+
@n2_50.round(0).should == @neg_two
|
60
|
+
@n2_51.round(0).should == @neg_two
|
61
|
+
@n2_49.round(0).should == @neg_two
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "BigDecimal::ROUND_UP" do
|
65
|
+
it "rounds values away from zero" do
|
66
|
+
@p1_50.round(0, BigDecimal::ROUND_UP).should == @two
|
67
|
+
@p1_51.round(0, BigDecimal::ROUND_UP).should == @two
|
68
|
+
@p1_49.round(0, BigDecimal::ROUND_UP).should == @two
|
69
|
+
@n1_50.round(0, BigDecimal::ROUND_UP).should == @neg_two
|
70
|
+
@n1_51.round(0, BigDecimal::ROUND_UP).should == @neg_two
|
71
|
+
@n1_49.round(0, BigDecimal::ROUND_UP).should == @neg_two
|
72
|
+
|
73
|
+
@p2_50.round(0, BigDecimal::ROUND_UP).should == @three
|
74
|
+
@p2_51.round(0, BigDecimal::ROUND_UP).should == @three
|
75
|
+
@p2_49.round(0, BigDecimal::ROUND_UP).should == @three
|
76
|
+
@n2_50.round(0, BigDecimal::ROUND_UP).should == @neg_three
|
77
|
+
@n2_51.round(0, BigDecimal::ROUND_UP).should == @neg_three
|
78
|
+
@n2_49.round(0, BigDecimal::ROUND_UP).should == @neg_three
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "BigDecimal::ROUND_DOWN" do
|
83
|
+
it "rounds values towards zero" do
|
84
|
+
@p1_50.round(0, BigDecimal::ROUND_DOWN).should == @one
|
85
|
+
@p1_51.round(0, BigDecimal::ROUND_DOWN).should == @one
|
86
|
+
@p1_49.round(0, BigDecimal::ROUND_DOWN).should == @one
|
87
|
+
@n1_50.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
|
88
|
+
@n1_51.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
|
89
|
+
@n1_49.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
|
90
|
+
|
91
|
+
@p2_50.round(0, BigDecimal::ROUND_DOWN).should == @two
|
92
|
+
@p2_51.round(0, BigDecimal::ROUND_DOWN).should == @two
|
93
|
+
@p2_49.round(0, BigDecimal::ROUND_DOWN).should == @two
|
94
|
+
@n2_50.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
|
95
|
+
@n2_51.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
|
96
|
+
@n2_49.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "BigDecimal::ROUND_HALF_UP" do
|
101
|
+
it "rounds values >= 5 up, otherwise down" do
|
102
|
+
@p1_50.round(0, BigDecimal::ROUND_HALF_UP).should == @two
|
103
|
+
@p1_51.round(0, BigDecimal::ROUND_HALF_UP).should == @two
|
104
|
+
@p1_49.round(0, BigDecimal::ROUND_HALF_UP).should == @one
|
105
|
+
@n1_50.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
|
106
|
+
@n1_51.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
|
107
|
+
@n1_49.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_one
|
108
|
+
|
109
|
+
@p2_50.round(0, BigDecimal::ROUND_HALF_UP).should == @three
|
110
|
+
@p2_51.round(0, BigDecimal::ROUND_HALF_UP).should == @three
|
111
|
+
@p2_49.round(0, BigDecimal::ROUND_HALF_UP).should == @two
|
112
|
+
@n2_50.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_three
|
113
|
+
@n2_51.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_three
|
114
|
+
@n2_49.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
ruby_bug "redmine:3803/4567", "1.9.2" do
|
119
|
+
describe "BigDecimal::ROUND_HALF_DOWN" do
|
120
|
+
it "rounds values > 5 up, otherwise down" do
|
121
|
+
@p1_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @one
|
122
|
+
@p1_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
|
123
|
+
@p1_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @one
|
124
|
+
@n1_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_one
|
125
|
+
@n1_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
|
126
|
+
@n1_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_one
|
127
|
+
|
128
|
+
@p2_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
|
129
|
+
@p2_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @three
|
130
|
+
@p2_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
|
131
|
+
@n2_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
|
132
|
+
@n2_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_three
|
133
|
+
@n2_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "BigDecimal::ROUND_CEILING" do
|
139
|
+
it "rounds values towards +infinity" do
|
140
|
+
@p1_50.round(0, BigDecimal::ROUND_CEILING).should == @two
|
141
|
+
@p1_51.round(0, BigDecimal::ROUND_CEILING).should == @two
|
142
|
+
@p1_49.round(0, BigDecimal::ROUND_CEILING).should == @two
|
143
|
+
@n1_50.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
|
144
|
+
@n1_51.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
|
145
|
+
@n1_49.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
|
146
|
+
|
147
|
+
@p2_50.round(0, BigDecimal::ROUND_CEILING).should == @three
|
148
|
+
@p2_51.round(0, BigDecimal::ROUND_CEILING).should == @three
|
149
|
+
@p2_49.round(0, BigDecimal::ROUND_CEILING).should == @three
|
150
|
+
@n2_50.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
|
151
|
+
@n2_51.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
|
152
|
+
@n2_49.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "BigDecimal::ROUND_FLOOR" do
|
157
|
+
it "rounds values towards -infinity" do
|
158
|
+
@p1_50.round(0, BigDecimal::ROUND_FLOOR).should == @one
|
159
|
+
@p1_51.round(0, BigDecimal::ROUND_FLOOR).should == @one
|
160
|
+
@p1_49.round(0, BigDecimal::ROUND_FLOOR).should == @one
|
161
|
+
@n1_50.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
|
162
|
+
@n1_51.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
|
163
|
+
@n1_49.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
|
164
|
+
|
165
|
+
@p2_50.round(0, BigDecimal::ROUND_FLOOR).should == @two
|
166
|
+
@p2_51.round(0, BigDecimal::ROUND_FLOOR).should == @two
|
167
|
+
@p2_49.round(0, BigDecimal::ROUND_FLOOR).should == @two
|
168
|
+
@n2_50.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
|
169
|
+
@n2_51.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
|
170
|
+
@n2_49.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
ruby_bug "redmine:3803/4567", "1.9.2" do
|
175
|
+
describe "BigDecimal::ROUND_HALF_EVEN" do
|
176
|
+
it "rounds values > 5 up, < 5 down and == 5 towards even neighbor" do
|
177
|
+
@p1_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
|
178
|
+
@p1_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
|
179
|
+
@p1_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @one
|
180
|
+
@n1_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
|
181
|
+
@n1_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
|
182
|
+
@n1_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_one
|
183
|
+
|
184
|
+
@p2_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
|
185
|
+
@p2_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @three
|
186
|
+
@p2_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
|
187
|
+
@n2_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
|
188
|
+
@n2_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_three
|
189
|
+
@n2_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|