mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 401b64c4e8
			
		
	
	
		401b64c4e8
		
	
	
	
	
		
			
			git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62656 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			179 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require_relative '../../spec_helper'
 | |
| require_relative 'fixtures/classes'
 | |
| 
 | |
| require 'bigdecimal'
 | |
| 
 | |
| describe "BigDecimal#add" do
 | |
| 
 | |
|   before :each do
 | |
|     @one = BigDecimal("1")
 | |
|     @zero = BigDecimal("0")
 | |
|     @two = BigDecimal("2")
 | |
|     @three = BigDecimal("3")
 | |
|     @ten = BigDecimal("10")
 | |
|     @eleven = BigDecimal("11")
 | |
|     @nan = BigDecimal("NaN")
 | |
|     @infinity = BigDecimal("Infinity")
 | |
|     @infinity_minus = BigDecimal("-Infinity")
 | |
|     @one_minus = BigDecimal("-1")
 | |
|     @frac_1 = BigDecimal("1E-99999")
 | |
|     @frac_2 = BigDecimal("0.9E-99999")
 | |
|     @frac_3 = BigDecimal("12345E10")
 | |
|     @frac_4 = BigDecimal("98765E10")
 | |
|     @dot_ones = BigDecimal("0.1111111111")
 | |
|   end
 | |
| 
 | |
|   it "returns a + b with given precision" do
 | |
|     # documentation states, that precision ist optional, but it ain't,
 | |
|     @two.add(@one, 1).should == @three
 | |
|     @one .add(@two, 1).should == @three
 | |
|     @one.add(@one_minus, 1).should == @zero
 | |
|     @ten.add(@one, 2).should == @eleven
 | |
|     @zero.add(@one, 1).should == @one
 | |
|     @frac_2.add(@frac_1, 10000).should == BigDecimal("1.9E-99999")
 | |
|     @frac_1.add(@frac_1, 10000).should == BigDecimal("2E-99999")
 | |
|     @frac_3.add(@frac_4, 0).should == BigDecimal("0.11111E16")
 | |
|     @frac_3.add(@frac_4, 1).should == BigDecimal("0.1E16")
 | |
|     @frac_3.add(@frac_4, 2).should == BigDecimal("0.11E16")
 | |
|     @frac_3.add(@frac_4, 3).should == BigDecimal("0.111E16")
 | |
|     @frac_3.add(@frac_4, 4).should == BigDecimal("0.1111E16")
 | |
|     @frac_3.add(@frac_4, 5).should == BigDecimal("0.11111E16")
 | |
|     @frac_3.add(@frac_4, 6).should == BigDecimal("0.11111E16")
 | |
|   end
 | |
| 
 | |
|   it "returns a + [Fixnum value] with given precision" do
 | |
|     (1..10).each {|precision|
 | |
|       @dot_ones.add(0, precision).should == BigDecimal("0." + "1" * precision)
 | |
|     }
 | |
|     BigDecimal("0.88").add(0, 1).should == BigDecimal("0.9")
 | |
|   end
 | |
| 
 | |
|   it "returns a + [Bignum value] with given precision" do
 | |
|     bignum = 10000000000000000000
 | |
|     (1..20).each {|precision|
 | |
|       @dot_ones.add(bignum, precision).should == BigDecimal("0.1E20")
 | |
|     }
 | |
|     (21..30).each {|precision|
 | |
|       @dot_ones.add(bignum, precision).should == BigDecimal(
 | |
|         "0.10000000000000000000" + "1" * (precision - 20) + "E20")
 | |
|     }
 | |
|   end
 | |
| 
 | |
| #  TODO:
 | |
| #  http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17374
 | |
| #
 | |
| #  This doesn't work on MRI and looks like a bug to me:
 | |
| #  one can use BigDecimal + Float, but not Bigdecimal.add(Float)
 | |
| #
 | |
| #  it "returns a + [Float value] with given precision" do
 | |
| #    (1..10).each {|precision|
 | |
| #      @dot_ones.add(0.0, precision).should == BigDecimal("0." + "1" * precision)
 | |
| #    }
 | |
| #
 | |
| #    BigDecimal("0.88").add(0.0, 1).should == BigDecimal("0.9")
 | |
| #  end
 | |
| 
 | |
|   it "favors the precision specified in the second argument over the global limit" do
 | |
|     BigDecimalSpecs.with_limit(1) do
 | |
|       BigDecimal('0.888').add(@zero, 3).should == BigDecimal('0.888')
 | |
|     end
 | |
| 
 | |
|     BigDecimalSpecs.with_limit(2) do
 | |
|       BigDecimal('0.888').add(@zero, 1).should == BigDecimal('0.9')
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   it "uses the current rounding mode if rounding is needed" do
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_UP) do
 | |
|       BigDecimal('0.111').add(@zero, 1).should == BigDecimal('0.2')
 | |
|       BigDecimal('-0.111').add(@zero, 1).should == BigDecimal('-0.2')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_DOWN) do
 | |
|       BigDecimal('0.999').add(@zero, 1).should == BigDecimal('0.9')
 | |
|       BigDecimal('-0.999').add(@zero, 1).should == BigDecimal('-0.9')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_HALF_UP) do
 | |
|       BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
 | |
|       BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_HALF_DOWN) do
 | |
|       BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
 | |
|       BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_HALF_EVEN) do
 | |
|       BigDecimal('0.75').add(@zero, 1).should == BigDecimal('0.8')
 | |
|       BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
 | |
|       BigDecimal('-0.75').add(@zero, 1).should == BigDecimal('-0.8')
 | |
|       BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_CEILING) do
 | |
|       BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
 | |
|       BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.8')
 | |
|     end
 | |
|     BigDecimalSpecs.with_rounding(BigDecimal::ROUND_FLOOR) do
 | |
|       BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.8')
 | |
|       BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   it "uses the default ROUND_HALF_UP rounding if it wasn't explicitly changed" do
 | |
|     BigDecimal('0.85').add(@zero, 1).should == BigDecimal('0.9')
 | |
|     BigDecimal('-0.85').add(@zero, 1).should == BigDecimal('-0.9')
 | |
|   end
 | |
| 
 | |
|   it "returns NaN if NaN is involved" do
 | |
|     @one.add(@nan, 10000).nan?.should == true
 | |
|     @nan.add(@one, 1).nan?.should == true
 | |
|   end
 | |
| 
 | |
|   it "returns Infinity or -Infinity if these are involved" do
 | |
|     @zero.add(@infinity, 1).should == @infinity
 | |
|     @frac_2.add(@infinity, 1).should == @infinity
 | |
|     @one_minus.add(@infinity, 1).should == @infinity
 | |
|     @two.add(@infinity, 1).should == @infinity
 | |
| 
 | |
|     @zero.add(@infinity_minus, 1).should == @infinity_minus
 | |
|     @frac_2.add(@infinity_minus, 1).should == @infinity_minus
 | |
|     @one_minus.add(@infinity_minus, 1).should == @infinity_minus
 | |
|     @two.add(@infinity_minus, 1).should == @infinity_minus
 | |
| 
 | |
|     @infinity.add(@zero, 1).should == @infinity
 | |
|     @infinity.add(@frac_2, 1).should == @infinity
 | |
|     @infinity.add(@one_minus, 1).should == @infinity
 | |
|     @infinity.add(@two, 1).should == @infinity
 | |
| 
 | |
|     @infinity_minus.add(@zero, 1).should == @infinity_minus
 | |
|     @infinity_minus.add(@frac_2, 1).should == @infinity_minus
 | |
|     @infinity_minus.add(@one_minus, 1).should == @infinity_minus
 | |
|     @infinity_minus.add(@two, 1).should == @infinity_minus
 | |
| 
 | |
|     @infinity.add(@infinity, 10000).should == @infinity
 | |
|     @infinity_minus.add(@infinity_minus, 10000).should == @infinity_minus
 | |
|   end
 | |
| 
 | |
|   it "returns NaN if Infinity + (- Infinity)" do
 | |
|     @infinity.add(@infinity_minus, 10000).nan?.should == true
 | |
|     @infinity_minus.add(@infinity, 10000).nan?.should == true
 | |
|   end
 | |
| 
 | |
|   it "raises TypeError when adds nil" do
 | |
|     lambda {
 | |
|       @one.add(nil, 10)
 | |
|     }.should raise_error(TypeError)
 | |
|     lambda {
 | |
|       @one.add(nil, 0)
 | |
|     }.should raise_error(TypeError)
 | |
|   end
 | |
| 
 | |
|   it "raises TypeError when precision parameter is nil" do
 | |
|     lambda {
 | |
|       @one.add(@one, nil)
 | |
|     }.should raise_error(TypeError)
 | |
|   end
 | |
| 
 | |
|   it "raises ArgumentError when precision parameter is negative" do
 | |
|     lambda {
 | |
|       @one.add(@one, -10)
 | |
|     }.should raise_error(ArgumentError)
 | |
|   end
 | |
| end
 |