1 require File.dirname(__FILE__) + '/../../spec_helper'
2 require File.dirname(__FILE__) + '/shared/modulo'
6 def self.check_both_nan(array)
7 array.length.should == 2
8 array[0].nan?.should == true
9 array[1].nan?.should == true
11 def self.check_both_bigdecimal(array)
12 array.length.should == 2
13 array[0].kind_of?(BigDecimal).should == true
14 array[1].kind_of?(BigDecimal).should == true
18 # TODO: figure out a way to do the shared specs with helpers instead
19 # of spec'ing a method that does not really exist
20 describe "BigDecimal#mod_part_of_divmod" do
21 # BigDecimal#divmod[1] behaves exactly like #modulo
24 def mod_part_of_dimvod(arg)
32 undef mod_part_of_dimvod
36 it_behaves_like :bigdecimal_modulo, :mod_part_of_dimvod
38 it "does NOT raise ZeroDivisionError if other is zero" do
39 bd6543 = BigDecimal.new("6543.21")
40 bd5667 = BigDecimal.new("5667.19")
41 a = BigDecimal("1.0000000000000000000000000000000000000000005")
42 b = BigDecimal("1.00000000000000000000000000000000000000000005")
44 bd5667.send(@method, 0).nan?.should == true
45 bd5667.send(@method, BigDecimal("0")).nan?.should == true
46 @zero.send(@method, @zero).nan?.should == true
50 describe "BigDecimal#divmod" do
53 @a = BigDecimal("42.00000000000000000001")
55 @zero = BigDecimal("0")
56 @zero_pos = BigDecimal("+0")
57 @zero_neg = BigDecimal("-0")
59 @one = BigDecimal("1")
60 @mixed = BigDecimal("1.23456789")
61 @pos_int = BigDecimal("2E5555")
62 @neg_int = BigDecimal("-2E5555")
63 @pos_frac = BigDecimal("2E-9999")
64 @neg_frac = BigDecimal("-2E-9999")
65 @nan = BigDecimal("NaN")
66 @infinity = BigDecimal("Infinity")
67 @infinity_minus = BigDecimal("-Infinity")
68 @one_minus = BigDecimal("-1")
69 @frac_1 = BigDecimal("1E-99999")
70 @frac_2 = BigDecimal("0.9E-99999")
72 @special_vals = [@infinity, @infinity_minus, @nan]
74 @one, @mixed, @pos_int, @neg_int, @pos_frac,
75 @neg_frac, @one_minus, @frac_1, @frac_2]
76 @zeroes = [@zero, @zero_pos, @zero_neg]
79 it "divides value, returns an array" do
81 res.kind_of?(Array).should == true
84 it "array contains quotient and modulus as BigDecimal" do
86 DivmodSpecs::check_both_bigdecimal(res)
87 res[0].should == BigDecimal('0.8E1')
88 res[1].should == BigDecimal('2.00000000000000000001')
90 BigDecimal('1').divmod(BigDecimal('2')).should == [0, 1]
91 BigDecimal('2').divmod(BigDecimal('1')).should == [2, 0]
93 BigDecimal('1').divmod(BigDecimal('-2')).should == [-1, -1]
94 BigDecimal('2').divmod(BigDecimal('-1')).should == [-2, 0]
96 BigDecimal('-1').divmod(BigDecimal('2')).should == [-1, 1]
97 BigDecimal('-2').divmod(BigDecimal('1')).should == [-2, 0]
100 it "Can be reversed with * and +" do
101 # Example taken from BigDecimal documentation
102 a = BigDecimal.new("42")
103 b = BigDecimal.new("9")
108 values = [@one, @one_minus, BigDecimal('2'), BigDecimal('-2'),
109 BigDecimal('5'), BigDecimal('-5'), BigDecimal('10'), BigDecimal('-10'),
110 BigDecimal('20'), BigDecimal('-20'), BigDecimal('100'), BigDecimal('-100'),
111 BigDecimal('1.23456789E10'), BigDecimal('-1.23456789E10')
114 # TODO: file MRI bug:
115 # BigDecimal('1').divmod(BigDecimal('3E-9'))[0] #=> 0.3E9,
116 # but really should be 0.333333333E9
117 ruby_bug "#206", "1.8" do #MRI's precision is very low in some cases
118 values << BigDecimal('1E-10')
119 values << BigDecimal('-1E-10')
120 values << BigDecimal('2E55')
121 values << BigDecimal('-2E55')
122 values << BigDecimal('2E-5555')
123 values << BigDecimal('-2E-5555')
126 values_and_zeroes = values + @zeroes
127 values_and_zeroes.each do |val1|
128 values.each do |val2|
129 res = val1.divmod(val2)
130 DivmodSpecs::check_both_bigdecimal(res)
131 res[0].should == ((val1/val2).floor)
132 res[1].should == (val1 - res[0] * val2)
138 it "properly handles special values" do
139 values = @special_vals + @zeroes
140 values.each do |val1|
141 values.each do |val2|
142 DivmodSpecs::check_both_nan(val1.divmod(val2))
146 @special_vals.each do |val1|
147 @regular_vals.each do |val2|
148 DivmodSpecs::check_both_nan(val1.divmod(val2))
152 @regular_vals.each do |val1|
153 @special_vals.each do |val2|
154 DivmodSpecs::check_both_nan(val1.divmod(val2))
159 it "returns an array of two NaNs if the argument is zero" do
160 values = @regular_vals + @special_vals
161 values.each do |val1|
162 @zeroes.each do |val2|
163 DivmodSpecs::check_both_nan(val1.divmod(val2))
168 it "raises TypeError if the argument cannot be coerced to BigDecimal" do
171 }.should raise_error(TypeError)