1 require File.dirname(__FILE__) + '/../../spec_helper'
2 require File.dirname(__FILE__) + '/fixtures/classes'
6 describe "BigDecimal#add" do
10 @zero = BigDecimal("0")
11 @two = BigDecimal("2")
12 @three = BigDecimal("3")
13 @ten = BigDecimal("10")
14 @eleven = BigDecimal("11")
15 @nan = BigDecimal("NaN")
16 @infinity = BigDecimal("Infinity")
17 @infinity_minus = BigDecimal("-Infinity")
18 @one_minus = BigDecimal("-1")
19 @frac_1 = BigDecimal("1E-99999")
20 @frac_2 = BigDecimal("0.9E-99999")
21 @frac_3 = BigDecimal("12345E10")
22 @frac_4 = BigDecimal("98765E10")
23 @dot_ones = BigDecimal("0.1111111111")
26 it "returns a + b with given precision" do
27 # documentation states, that precision ist optional, but it ain't,
28 @two.add(@one, 1).should == @three
29 @one .add(@two, 1).should == @three
30 @one.add(@one_minus, 1).should == @zero
31 @ten.add(@one, 2).should == @eleven
32 @zero.add(@one, 1).should == @one
33 @frac_2.add(@frac_1, 10000).should == BigDecimal("1.9E-99999")
34 @frac_1.add(@frac_1, 10000).should == BigDecimal("2E-99999")
35 @frac_3.add(@frac_4, 0).should == BigDecimal("0.11111E16")
36 @frac_3.add(@frac_4, 1).should == BigDecimal("0.1E16")
37 @frac_3.add(@frac_4, 2).should == BigDecimal("0.11E16")
38 @frac_3.add(@frac_4, 3).should == BigDecimal("0.111E16")
39 @frac_3.add(@frac_4, 4).should == BigDecimal("0.1111E16")
40 @frac_3.add(@frac_4, 5).should == BigDecimal("0.11111E16")
41 @frac_3.add(@frac_4, 6).should == BigDecimal("0.11111E16")
44 it "returns a + [Fixnum value] with given precision" do
45 (1..10).each {|precision|
46 @dot_ones.add(0, precision).should == BigDecimal("0." + "1" * precision)
48 BigDecimal("0.88").add(0, 1).should == BigDecimal("0.9")
51 it "returns a + [Bignum value] with given precision" do
52 bignum = 10000000000000000000
53 (1..20).each {|precision|
54 @dot_ones.add(bignum, precision).should == BigDecimal("0.1E20")
56 (21..30).each {|precision|
57 @dot_ones.add(bignum, precision).should == BigDecimal(
58 "0.10000000000000000000" + "1" * (precision - 20) + "E20")
63 # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17374
65 # This doesn't work on MRI and looks like a bug to me:
66 # one can use BigDecimal + Float, but not Bigdecimal.add(Float)
68 # it "returns a + [Float value] with given precision" do
69 # (1..10).each {|precision|
70 # @dot_ones.add(0.0, precision).should == BigDecimal("0." + "1" * precision)
73 # BigDecimal("0.88").add(0.0, 1).should == BigDecimal("0.9")
76 it "favors the precision specified in the second argument over the global limit" do
77 BigDecimalSpecs::with_limit(1) do
78 BigDecimal('0.888').add(@zero, 3).should == BigDecimal('0.888')
81 BigDecimalSpecs::with_limit(2) do
82 BigDecimal('0.888').add(@zero, 1).should == BigDecimal('0.9')
86 it "uses the current rounding mode if rounding is needed" do
87 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_UP) do
88 BigDecimal('0.111').add(@zero, 1).should == BigDecimal('0.2')
89 BigDecimal('-0.111').add(@zero, 1).should == BigDecimal('-0.2')
91 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_DOWN) do
92 BigDecimal('0.999').add(@zero, 1).should == BigDecimal('0.9')
93 BigDecimal('-0.999').add(@zero, 1).should == BigDecimal('-0.9')
95 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_HALF_UP) do
96 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
97 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
99 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_HALF_DOWN) do
100 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
101 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
103 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_HALF_EVEN) do
104 BigDecimal('0.75').add(@zero, 1).should == BigDecimal('0.8')
105 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
106 BigDecimal('-0.75').add(@zero, 1).should == BigDecimal('-0.8')
107 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
109 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_CEILING) do
110 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
111 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
113 BigDecimalSpecs::with_rounding(BigDecimal::ROUND_FLOOR) do
114 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
115 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
119 it "uses the default ROUND_HALF_UP rounding if it wasn't explicitly changed" do
120 BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
121 BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
124 it "returns NaN if NaN is involved" do
125 @one.add(@nan, 10000).nan?.should == true
126 @nan.add(@one, 1).nan?.should == true
129 it "returns Infinity or -Infinity if these are involved" do
130 @zero.add(@infinity, 1).should == @infinity
131 @frac_2.add(@infinity, 1).should == @infinity
132 @one_minus.add(@infinity, 1).should == @infinity
133 @two.add(@infinity, 1).should == @infinity
135 @zero.add(@infinity_minus, 1).should == @infinity_minus
136 @frac_2.add(@infinity_minus, 1).should == @infinity_minus
137 @one_minus.add(@infinity_minus, 1).should == @infinity_minus
138 @two.add(@infinity_minus, 1).should == @infinity_minus
140 @infinity.add(@zero, 1).should == @infinity
141 @infinity.add(@frac_2, 1).should == @infinity
142 @infinity.add(@one_minus, 1).should == @infinity
143 @infinity.add(@two, 1).should == @infinity
145 @infinity_minus.add(@zero, 1).should == @infinity_minus
146 @infinity_minus.add(@frac_2, 1).should == @infinity_minus
147 @infinity_minus.add(@one_minus, 1).should == @infinity_minus
148 @infinity_minus.add(@two, 1).should == @infinity_minus
150 @infinity.add(@infinity, 10000).should == @infinity
151 @infinity_minus.add(@infinity_minus, 10000).should == @infinity_minus
154 it "returns NaN if Infinity + (- Infinity)" do
155 @infinity.add(@infinity_minus, 10000).nan?.should == true
156 @infinity_minus.add(@infinity, 10000).nan?.should == true
159 it "raises TypeError when adds nil" do
162 }.should raise_error(TypeError)
165 }.should raise_error(TypeError)
168 it "raises TypeError when precision parameter is nil" do
171 }.should raise_error(TypeError)
174 it "raises ArgumentError when precision parameter is negative" do
177 }.should raise_error(ArgumentError)