add test suite for BigDecimal

This commit is contained in:
Watson
2014-06-13 23:33:46 +09:00
parent 6da4b5a1c0
commit 5851bbcac4
27 changed files with 1791 additions and 0 deletions

3
test/TestBigDecimal/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.repl_history
build
resources/*.nib

View File

@@ -0,0 +1,3 @@
Base
- mspec f8e8503667399547d270181728d2a5e60f058073
- rubyspec 5cef74ea771bd733ff1c8d39b22b991c39fcb1d4

View File

@@ -0,0 +1,9 @@
$:.unshift("../../lib")
require 'motion/project/template/ios'
# require 'motion/project/template/osx'
Motion::Project::App.setup do |app|
# Use `rake config' to see complete project settings.
app.name = 'TestBigDecimal'
app.deployment_target = ENV['deployment_target'] if ENV['deployment_target']
end

View File

@@ -0,0 +1,5 @@
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
true
end
end

View File

@@ -0,0 +1,17 @@
module BigDecimalSpecs
# helper method to sure that the global limit is reset back
def self.with_limit(l)
old = BigDecimal.limit(l)
yield
ensure
BigDecimal.limit(old)
end
def self.with_rounding(r)
old = BigDecimal.mode(BigDecimal::ROUND_MODE)
BigDecimal.mode(BigDecimal::ROUND_MODE, r)
yield
ensure
BigDecimal.mode(BigDecimal::ROUND_MODE, old)
end
end

View File

@@ -0,0 +1,200 @@
class Object
alias_method :__mspec_object_id__, :object_id
end
module Mock
def self.reset
@mocks = @stubs = @objects = nil
end
def self.objects
@objects ||= {}
end
def self.mocks
@mocks ||= Hash.new { |h,k| h[k] = [] }
end
def self.stubs
@stubs ||= Hash.new { |h,k| h[k] = [] }
end
def self.replaced_name(obj, sym)
:"__mspec_#{obj.__mspec_object_id__}_#{sym}__"
end
def self.replaced_key(obj, sym)
[replaced_name(obj, sym), sym]
end
def self.has_key?(keys, sym)
!!keys.find { |k| k.first == sym }
end
def self.replaced?(sym)
has_key?(mocks.keys, sym) or has_key?(stubs.keys, sym)
end
def self.clear_replaced(key)
mocks.delete key
stubs.delete key
end
def self.mock_respond_to?(obj, sym, include_private = false)
name = replaced_name(obj, :respond_to?)
if replaced? name
obj.__send__ name, sym, include_private
else
obj.respond_to? sym, include_private
end
end
def self.install_method(obj, sym, type=nil)
meta = obj.singleton_class
key = replaced_key obj, sym
sym = sym.to_sym
if (sym == :respond_to? or mock_respond_to?(obj, sym, true)) and !replaced?(key.first)
meta.__send__ :alias_method, key.first, sym
end
meta.class_eval do
define_method(sym) {|*args, &block|
Mock.verify_call self, sym, *args, &block
}
end
proxy = MockProxy.new type
if proxy.mock?
# TODO
# MSpec.expectation
# MSpec.actions :expectation, MSpec.current.state
end
if proxy.stub?
stubs[key].unshift proxy
else
mocks[key] << proxy
end
objects[key] = obj
proxy
end
def self.name_or_inspect(obj)
obj.instance_variable_get(:@name) || obj.inspect
end
def self.verify_count
mocks.each do |key, proxies|
obj = objects[key]
proxies.each do |proxy|
qualifier, count = proxy.count
pass = case qualifier
when :at_least
proxy.calls >= count
when :at_most
proxy.calls <= count
when :exactly
proxy.calls == count
when :any_number_of_times
true
else
false
end
unless pass
SpecExpectation.fail_with(
"Mock '#{name_or_inspect obj}' expected to receive '#{key.last}' " \
"#{qualifier.to_s.sub('_', ' ')} #{count} times",
"but received it #{proxy.calls} times")
end
end
end
end
def self.verify_call(obj, sym, *args, &block)
compare = *args
behaves_like_ruby_1_9 = *[]
if (behaves_like_ruby_1_9)
compare = compare.first if compare.length <= 1
end
key = replaced_key obj, sym
[mocks, stubs].each do |proxies|
proxies[key].each do |proxy|
pass = case proxy.arguments
when :any_args
true
when :no_args
compare.nil?
else
proxy.arguments == compare
end
if proxy.yielding?
if block
proxy.yielding.each do |args_to_yield|
if block.arity == -1 || block.arity == args_to_yield.size
block.call(*args_to_yield)
else
SpecExpectation.fail_with(
"Mock '#{name_or_inspect obj}' asked to yield " \
"|#{proxy.yielding.join(', ')}| on #{sym}\n",
"but a block with arity #{block.arity} was passed")
end
end
else
SpecExpectation.fail_with(
"Mock '#{name_or_inspect obj}' asked to yield " \
"|[#{proxy.yielding.join('], [')}]| on #{sym}\n",
"but no block was passed")
end
end
if pass
proxy.called
if proxy.raising?
raise proxy.raising
else
return proxy.returning
end
end
end
end
if sym.to_sym == :respond_to?
mock_respond_to? obj, compare
else
SpecExpectation.fail_with("Mock '#{name_or_inspect obj}': method #{sym}\n",
"called with unexpected arguments (#{Array(compare).join(' ')})")
end
end
def self.cleanup
objects.each do |key, obj|
if obj.kind_of? MockIntObject
clear_replaced key
next
end
replaced = key.first
sym = key.last
meta = obj.singleton_class
if mock_respond_to? obj, replaced, true
meta.__send__ :alias_method, sym, replaced
meta.__send__ :remove_method, replaced
else
meta.__send__ :remove_method, sym
end
clear_replaced key
end
ensure
reset
end
end

View File

@@ -0,0 +1,26 @@
class Object
def stub!(sym)
Mock.install_method self, sym, :stub
end
def should_receive(sym)
Mock.install_method self, sym
end
def should_not_receive(sym)
proxy = Mock.install_method self, sym
proxy.exactly(0).times
end
def mock(name, options={})
MockObject.new name, options
end
def mock_int(val)
MockIntObject.new(val)
end
def mock_numeric(name, options={})
NumericMockObject.new name, options
end
end

View File

@@ -0,0 +1,186 @@
class MockObject
def initialize(name, options={})
@name = name
@null = options[:null_object]
end
def method_missing(sym, *args, &block)
@null ? self : super
end
private :method_missing
end
class NumericMockObject < Numeric
def initialize(name, options={})
@name = name
@null = options[:null_object]
end
def method_missing(sym, *args, &block)
@null ? self : super
end
def singleton_method_added(val)
end
end
class MockIntObject
def initialize(val)
@value = val
@calls = 0
key = [self, :to_int]
Mock.objects[key] = self
Mock.mocks[key] << self
end
attr_reader :calls
def to_int
@calls += 1
@value
end
def count
[:at_least, 1]
end
end
class MockProxy
attr_reader :raising, :yielding
def initialize(type=nil)
@multiple_returns = nil
@returning = nil
@raising = nil
@yielding = []
@arguments = :any_args
@type = type || :mock
end
def mock?
@type == :mock
end
def stub?
@type == :stub
end
def count
@count ||= mock? ? [:exactly, 1] : [:any_number_of_times, 0]
end
def arguments
@arguments
end
def returning
if @multiple_returns
if @returning.size == 1
@multiple_returns = false
return @returning = @returning.shift
end
return @returning.shift
end
@returning
end
def times
self
end
def calls
@calls ||= 0
end
def called
@calls = calls + 1
end
def exactly(n)
@count = [:exactly, n_times(n)]
self
end
def at_least(n)
@count = [:at_least, n_times(n)]
self
end
def at_most(n)
@count = [:at_most, n_times(n)]
self
end
def once
exactly 1
end
def twice
exactly 2
end
def any_number_of_times
@count = [:any_number_of_times, 0]
self
end
def with(*args)
raise ArgumentError, "you must specify the expected arguments" if args.empty?
@arguments = *args
behaves_like_ruby_1_9 = *[]
if (behaves_like_ruby_1_9)
@arguments = @arguments.first if @arguments.length <= 1
end
self
end
def and_return(*args)
case args.size
when 0
@returning = nil
when 1
@returning = args[0]
else
@multiple_returns = true
@returning = args
count[1] = args.size if count[1] < args.size
end
self
end
def and_raise(exception)
if exception.kind_of? String
@raising = RuntimeError.new exception
else
@raising = exception
end
end
def raising?
@raising != nil
end
def and_yield(*args)
@yielding << args
self
end
def yielding?
!@yielding.empty?
end
private
def n_times(n)
case n
when :once
1
when :twice
2
else
Integer n
end
end
end

View File

@@ -0,0 +1,9 @@
class Object
def ruby_version_is(*args)
yield
end
def ruby_bug(bug, version)
yield
end
end

View File

@@ -0,0 +1,50 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#abs" do
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
@two = BigDecimal("2")
@three = BigDecimal("3")
@mixed = BigDecimal("1.23456789")
@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")
end
it "returns the absolute value" do
# pos_int = BigDecimal("2E5555")
# neg_int = BigDecimal("-2E5555")
# pos_frac = BigDecimal("2E-9999")
# neg_frac = BigDecimal("-2E-9999")
# pos_int.abs.should == pos_int
# neg_int.abs.should == pos_int
# pos_frac.abs.should == pos_frac
# neg_frac.abs.should == pos_frac
@one.abs.should == 1
@two.abs.should == 2
@three.abs.should == 3
@mixed.abs.should == @mixed
@one_minus.abs.should == @one
end
it "properly handles special values" do
# @infinity.abs.should == @infinity
# @infinity_minus.abs.should == @infinity
# @nan.abs.nan?.should == true # have to do it this way, since == doesn't work on NaN
@zero.abs.should == 0
# @zero.abs.sign.should == BigDecimal::SIGN_POSITIVE_ZERO
@zero_pos.abs.should == 0
# @zero_pos.abs.sign.should == BigDecimal::SIGN_POSITIVE_ZERO
@zero_neg.abs.should == 0
# @zero_neg.abs.sign.should == BigDecimal::SIGN_POSITIVE_ZERO
end
end

View File

@@ -0,0 +1,123 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#ceil" do
before do
@zero = BigDecimal("0")
@one = BigDecimal("1")
@three = BigDecimal("3")
@four = BigDecimal("4")
@mixed = BigDecimal("1.23456789")
@mixed_big = BigDecimal("1.23456789E100")
@pos_int = BigDecimal("2E5")
@neg_int = BigDecimal("-2E5")
# @pos_frac = BigDecimal("2E-9999")
# @neg_frac = BigDecimal("-2E-9999")
# @infinity = BigDecimal("Infinity")
# @infinity_neg = BigDecimal("-Infinity")
# @nan = BigDecimal("NaN")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
end
# ruby_version_is "" ... "1.9" do
# it "returns a BigDecimal" do
# @mixed.ceil.kind_of?(BigDecimal).should == true
# @pos_int.ceil(2).kind_of?(BigDecimal).should == true
# end
# end
ruby_version_is "1.9" do
it "returns an Integer, if n is unspecified" do
@mixed.ceil.kind_of?(Integer).should == true
end
it "returns a BigDecimal, if n is specified" do
@pos_int.ceil(2).kind_of?(BigDecimal).should == true
end
end
it "returns the smallest integer greater or equal to self, if n is unspecified" do
@pos_int.ceil.should == @pos_int
@neg_int.ceil.should == @neg_int
# @pos_frac.ceil.should == BigDecimal("1")
# @neg_frac.ceil.should == @zero
@zero.ceil.should == 0
@zero_pos.ceil.should == @zero_pos
@zero_neg.ceil.should == @zero_neg
BigDecimal('2.3').ceil.should == 3
BigDecimal('2.5').ceil.should == 3
BigDecimal('2.9999').ceil.should == 3
BigDecimal('-2.3').ceil.should == -2
BigDecimal('-2.5').ceil.should == -2
BigDecimal('-2.9999').ceil.should == -2
end
# ruby_version_is "" ... "1.9" do
# it "returns the same value, if self is special value" do
# @infinity.ceil.should == @infinity
# @infinity_neg.ceil.should == @infinity_neg
# @nan.ceil.nan?.should == true
# end
# end
# ruby_version_is "1.9" do
# it "raises exception, if self is special value" do
# lambda { @infinity.ceil }.should raise_error(FloatDomainError)
# lambda { @infinity_neg.ceil }.should raise_error(FloatDomainError)
# lambda { @nan.ceil }.should raise_error(FloatDomainError)
# end
# end
it "returns n digits right of the decimal point if given n > 0" do
@mixed.ceil(1).should == BigDecimal("1.3")
@mixed.ceil(5).should == BigDecimal("1.23457")
BigDecimal("-0.03").ceil(1).should == BigDecimal("0")
BigDecimal("0.03").ceil(1).should == BigDecimal("0.1")
BigDecimal("23.45").ceil(0).should == BigDecimal('24')
BigDecimal("23.45").ceil(1).should == BigDecimal('23.5')
BigDecimal("23.45").ceil(2).should == BigDecimal('23.45')
BigDecimal("-23.45").ceil(0).should == BigDecimal('-23')
BigDecimal("-23.45").ceil(1).should == BigDecimal('-23.4')
BigDecimal("-23.45").ceil(2).should == BigDecimal('-23.45')
BigDecimal("2E-10").ceil(0).should == @one
BigDecimal("2E-10").ceil(9).should == BigDecimal('1E-9')
BigDecimal("2E-10").ceil(10).should == BigDecimal('2E-10')
BigDecimal("2E-10").ceil(11).should == BigDecimal('2E-10')
# (1..10).each do |n|
# # 0.4, 0.34, 0.334, etc.
# (@one.div(@three,20)).ceil(n).should == BigDecimal("0.#{'3'*(n-1)}4")
# # 1.4, 1.34, 1.334, etc.
# (@four.div(@three,20)).ceil(n).should == BigDecimal("1.#{'3'*(n-1)}4")
# (BigDecimal('31').div(@three,20)).ceil(n).should == BigDecimal("10.#{'3'*(n-1)}4")
# end
# (1..10).each do |n|
# # -0.4, -0.34, -0.334, etc.
# (-@one.div(@three,20)).ceil(n).should == BigDecimal("-0.#{'3'* n}")
# end
# (1..10).each do |n|
# (@three.div(@one,20)).ceil(n).should == @three
# end
# (1..10).each do |n|
# (-@three.div(@one,20)).ceil(n).should == -@three
# end
end
it "sets n digits left of the decimal point to 0, if given n < 0" do
BigDecimal("13345.234").ceil(-2).should == BigDecimal("13400.0")
@mixed_big.ceil(-99).should == BigDecimal("0.13E101")
@mixed_big.ceil(-100).should == BigDecimal("0.2E101")
@mixed_big.ceil(-95).should == BigDecimal("0.123457E101")
BigDecimal("1E10").ceil(-30).should == BigDecimal('1E30')
BigDecimal("-1E10").ceil(-30).should == @zero
end
end

View File

@@ -0,0 +1,26 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#coerce" do
it "returns [other, self] both as BigDecimal" do
one = BigDecimal("1.0")
five_point_28 = BigDecimal("5.28")
zero_minus = BigDecimal("-0.0")
some_value = 3243423
BigDecimal("1.2").coerce(1).should == [one, BigDecimal("1.2")]
# five_point_28.coerce(1.0).should == [one, BigDecimal("5.28")]
one.coerce(one).should == [one, one]
one.coerce(2.5).should == [2.5, one]
BigDecimal("1").coerce(3.14).should == [3.14, one]
a, b = zero_minus.coerce(some_value)
a.should == BigDecimal(some_value.to_s)
b.should == zero_minus
a, b = one.coerce(some_value)
a.should == BigDecimal(some_value.to_s)
# b.to_f.should be_close(1.0, TOLERANCE) # can we take out the to_f once BigDecimal#- is implemented?
b.should == one
end
end

View File

@@ -0,0 +1,105 @@
# require 'bigdecimal'
# require 'rational'
describe "BigDecimal#/" do
@method = :/
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_plus = BigDecimal("+0")
@zero_minus = BigDecimal("-0")
@two = BigDecimal("2")
@three = BigDecimal("3")
@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")
@float = 1.48
@rational = Rational(17,3)
end
it "returns a / b" do
@two.send(@method, @one, *@object).should == @two
@one.send(@method, @two, *@object).should == BigDecimal("0.5")
# @eleven.send(@method, @three, *@object).should be_close(@three + (@two / @three), TOLERANCE)
@one.send(@method, @one_minus, *@object).should == @one_minus
@one_minus.send(@method, @one_minus, *@object).should == @one
# @frac_2.send(@method, @frac_1, *@object).should == BigDecimal("0.9")
# @frac_1.send(@method, @frac_1, *@object).should == @one
# @one.send(@method, BigDecimal('-2E5555'), *@object).should == BigDecimal('-0.5E-5555')
# @one.send(@method, BigDecimal('2E-5555'), *@object).should == BigDecimal('0.5E5555')
end
# it "returns 0 if divided by Infinity" do
# @zero.send(@method, @infinity, *@object).should == 0
# @frac_2.send(@method, @infinity, *@object).should == 0
# end
# it "returns (+|-) Infinity if (+|-) Infinity divided by one" do
# @infinity_minus.send(@method, @one, *@object).should == @infinity_minus
# @infinity.send(@method, @one, *@object).should == @infinity
# @infinity_minus.send(@method, @one_minus, *@object).should == @infinity
# end
# it "returns NaN if Infinity / ((+|-) Infinity)" do
# @infinity.send(@method, @infinity_minus, *@object).nan?.should == true
# @infinity_minus.send(@method, @infinity, *@object).nan?.should == true
# end
# it "returns (+|-) Infinity if divided by zero" do
# @one.send(@method, @zero, *@object).should == @infinity
# @one.send(@method, @zero_plus, *@object).should == @infinity
# @one.send(@method, @zero_minus, *@object).should == @infinity_minus
# end
it "returns NaN if zero is divided by zero" do
@zero.send(@method, @zero, *@object).nan?.should == true
@zero_minus.send(@method, @zero_plus, *@object).nan?.should == true
@zero_plus.send(@method, @zero_minus, *@object).nan?.should == true
end
# context "with a Float" do
# ruby_version_is "".."1.9" do
# it "returns a Float" do
# result = @eleven.send(@method, @float, *@object)
# result.should be_close(7.4324324324324325, TOLERANCE)
# result.kind_of?(Float).should == true
# end
# end
# ruby_version_is "2.0.0" do
# it "returns a BigDecimal" do
# result = @eleven.send(@method, @float, *@object)
# result.should be_close(7.4324324324324325, TOLERANCE)
# result.should be_an_instance_of(BigDecimal)
# end
# end
# end
# context "with a Rational" do
# ruby_version_is ""..."1.9" do
# it "returns a Float" do
# result = @eleven.send(@method, @rational, *@object)
# result.should be_close(1.94117647058824, TOLERANCE)
# result.kind_of?(Float).should == true
# end
# end
# ruby_version_is "1.9"..."2.0" do
# it "raises a TypeError" do
# lambda { @eleven.send(@method, @rational, *@object) }.should raise_error(TypeError)
# end
# end
# ruby_version_is "2.0.0" do
# it "returns a BigDecimal" do
# result = @eleven.send(@method, @rational, *@object)
# result.should be_close(1.94117647058824, TOLERANCE)
# result.kind_of?(BigDecimal).should == true
# end
# end
# end
end

View File

@@ -0,0 +1,110 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#floor" do
before do
@one = BigDecimal("1")
@three = BigDecimal("3")
@four = BigDecimal("4")
@zero = BigDecimal("0")
@mixed = BigDecimal("1.23456789")
@mixed_big = BigDecimal("1.23456789E100")
@pos_int = BigDecimal("2E5")
@neg_int = BigDecimal("-2E5")
# @pos_frac = BigDecimal("2E-9999")
# @neg_frac = BigDecimal("-2E-9999")
# @infinity = BigDecimal("Infinity")
# @infinity_neg = BigDecimal("-Infinity")
# @nan = BigDecimal("NaN")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
end
it "returns the greatest integer smaller or equal to self" do
@pos_int.floor.should == @pos_int
@neg_int.floor.should == @neg_int
# @pos_frac.floor.should == @zero
# @neg_frac.floor.should == BigDecimal("-1")
@zero.floor.should == 0
@zero_pos.floor.should == @zero_pos
@zero_neg.floor.should == @zero_neg
BigDecimal('2.3').floor.should == 2
BigDecimal('2.5').floor.should == 2
BigDecimal('2.9999').floor.should == 2
BigDecimal('-2.3').floor.should == -3
BigDecimal('-2.5').floor.should == -3
BigDecimal('-2.9999').floor.should == -3
BigDecimal('0.8').floor.should == 0
BigDecimal('-0.8').floor.should == -1
end
# ruby_version_is "" ... "1.9" do
# it "returns the same value, if self is special value" do
# @infinity.floor.should == @infinity
# @infinity_neg.floor.should == @infinity_neg
# @nan.floor.nan?.should == true
# end
# end
# ruby_version_is "1.9" do
# it "raises exception, if self is special value" do
# lambda { @infinity.floor }.should raise_error(FloatDomainError)
# lambda { @infinity_neg.floor }.should raise_error(FloatDomainError)
# lambda { @nan.floor }.should raise_error(FloatDomainError)
# end
# end
it "returns n digits right of the decimal point if given n > 0" do
@mixed.floor(1).should == BigDecimal("1.2")
@mixed.floor(5).should == BigDecimal("1.23456")
BigDecimal("-0.03").floor(1).should == BigDecimal("-0.1")
BigDecimal("0.03").floor(1).should == BigDecimal("0")
BigDecimal("23.45").floor(0).should == BigDecimal('23')
BigDecimal("23.45").floor(1).should == BigDecimal('23.4')
BigDecimal("23.45").floor(2).should == BigDecimal('23.45')
BigDecimal("-23.45").floor(0).should == BigDecimal('-24')
BigDecimal("-23.45").floor(1).should == BigDecimal('-23.5')
BigDecimal("-23.45").floor(2).should == BigDecimal('-23.45')
BigDecimal("2E-10").floor(0).should == @zero
BigDecimal("2E-10").floor(9).should == @zero
BigDecimal("2E-10").floor(10).should == BigDecimal('2E-10')
BigDecimal("2E-10").floor(11).should == BigDecimal('2E-10')
# (1..10).each do |n|
# # 0.3, 0.33, 0.333, etc.
# (@one.div(@three,20)).floor(n).should == BigDecimal("0.#{'3'*n}")
# # 1.3, 1.33, 1.333, etc.
# (@four.div(@three,20)).floor(n).should == BigDecimal("1.#{'3'*n}")
# (BigDecimal('31').div(@three,20)).floor(n).should == BigDecimal("10.#{'3'*n}")
# end
# (1..10).each do |n|
# # -0.4, -0.34, -0.334, etc.
# (-@one.div(@three,20)).floor(n).should == BigDecimal("-0.#{'3'*(n-1)}4")
# end
# (1..10).each do |n|
# (@three.div(@one,20)).floor(n).should == @three
# end
# (1..10).each do |n|
# (-@three.div(@one,20)).floor(n).should == -@three
# end
end
it "sets n digits left of the decimal point to 0, if given n < 0" do
BigDecimal("13345.234").floor(-2).should == BigDecimal("13300.0")
@mixed_big.floor(-99).should == BigDecimal("0.12E101")
@mixed_big.floor(-100).should == BigDecimal("0.1E101")
@mixed_big.floor(-95).should == BigDecimal("0.123456E101")
(1..10).each do |n|
BigDecimal('1.8').floor(-n).should == @zero
end
BigDecimal("1E10").floor(-30).should == @zero
BigDecimal("-1E10").floor(-30).should == BigDecimal('-1E30')
end
end

View File

@@ -0,0 +1,58 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#-" do
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@two = BigDecimal("2")
@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")
end
it "returns a - b" do
(@two - @one).should == @one
(@one - @two).should == @one_minus
(@one - @one_minus).should == @two
# (@frac_2 - @frac_1).should == BigDecimal("-0.1E-99999")
(@two - @two).should == @zero
# (@frac_1 - @frac_1).should == @zero
(BigDecimal('1.23456789') - BigDecimal('1.2')).should == BigDecimal("0.03456789")
end
# it "returns NaN if NaN is involved" do
# (@one - @nan).nan?.should == true
# (@nan - @one).nan?.should == true
# (@nan - @nan).nan?.should == true
# (@nan - @infinity).nan?.should == true
# (@nan - @infinity_minus).nan?.should == true
# (@infinity - @nan).nan?.should == true
# (@infinity_minus - @nan).nan?.should == true
# end
# it "returns NaN both operands are infinite with the same sign" do
# (@infinity - @infinity).nan?.should == true
# (@infinity_minus - @infinity_minus).nan?.should == true
# end
# it "returns Infinity or -Infinity if these are involved" do
# (@infinity - @infinity_minus).should == @infinity
# (@infinity_minus - @infinity).should == @infinity_minus
# (@infinity - @zero).should == @infinity
# (@infinity - @frac_2).should == @infinity
# (@infinity - @two).should == @infinity
# (@infinity - @one_minus).should == @infinity
# (@zero - @infinity).should == @infinity_minus
# (@frac_2 - @infinity).should == @infinity_minus
# (@two - @infinity).should == @infinity_minus
# (@one_minus - @infinity).should == @infinity_minus
# end
end

View File

@@ -0,0 +1,145 @@
# require 'bigdecimal'
describe "BigDecimal#%" do
@method = :%
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
@two = BigDecimal("2")
@three = BigDecimal("3")
@mixed = BigDecimal("1.23456789")
@nan = BigDecimal("NaN")
@infinity = BigDecimal("Infinity")
@infinity_minus = BigDecimal("-Infinity")
@one_minus = BigDecimal("-1")
# @frac_1 = BigDecimal("1E-9999")
# @frac_2 = BigDecimal("0.9E-9999")
end
it "returns self modulo other" do
bd6543 = BigDecimal.new("6543.21")
bd5667 = BigDecimal.new("5667.19")
a = BigDecimal("1.0000000000000000000000000000000000000000005")
b = BigDecimal("1.00000000000000000000000000000000000000000005")
bd6543.send(@method, 137).should == BigDecimal("104.21")
# bd5667.send(@method, bignum_value).should == 5667.19
bd6543.send(@method, BigDecimal("137.24")).should == BigDecimal("92.93")
# bd6543.send(@method, 137).should be_close(6543.21.%(137), TOLERANCE)
bd6543.send(@method, 137).should == bd6543 % 137
# bd5667.send(@method, bignum_value).should be_close(5667.19.%(0xffffffff), TOLERANCE)
# bd5667.send(@method, bignum_value).should == bd5667.%(0xffffffff)
# bd6543.send(@method, 137.24).should be_close(6543.21.%(137.24), TOLERANCE)
# a.send(@method, b).should == BigDecimal("0.45E-42")
@zero.send(@method, @one).should == @zero
@zero.send(@method, @one_minus).should == @zero
@two.send(@method, @one).should == @zero
@one.send(@method, @two).should == @one
# @frac_1.send(@method, @one).should == @frac_1
# @frac_2.send(@method, @one).should == @frac_2
@one_minus.send(@method, @one_minus).should == @zero
@one_minus.send(@method, @one).should == @zero
@one_minus.send(@method, @two).should == @one
@one.send(@method, -@two).should == -@one
@one_minus.modulo(BigDecimal('0.9')).should == BigDecimal('0.8')
@one.modulo(BigDecimal('-0.9')).should == BigDecimal('-0.8')
@one_minus.modulo(BigDecimal('0.8')).should == BigDecimal('0.6')
@one.modulo(BigDecimal('-0.8')).should == BigDecimal('-0.6')
@one_minus.modulo(BigDecimal('0.6')).should == BigDecimal('0.2')
@one.modulo(BigDecimal('-0.6')).should == BigDecimal('-0.2')
@one_minus.modulo(BigDecimal('0.5')).should == @zero
@one.modulo(BigDecimal('-0.5')).should == @zero
@one_minus.modulo(BigDecimal('-0.5')).should == @zero
@one_minus.modulo(BigDecimal('0.4')).should == BigDecimal('0.2')
@one.modulo(BigDecimal('-0.4')).should == BigDecimal('-0.2')
@one_minus.modulo(BigDecimal('0.3')).should == BigDecimal('0.2')
@one_minus.modulo(BigDecimal('0.2')).should == @zero
end
ruby_bug "#", "1.9.2" do
it "returns a [Float value] when the argument is Float" do
@two.send(@method, 2.0).should == 0.0
@one.send(@method, 2.0).should == 1.0
res = @two.send(@method, 5.0)
res.kind_of?(BigDecimal).should == true
end
end
# it "returns NaN if NaN is involved" do
# @nan.send(@method, @nan).nan?.should == true
# @nan.send(@method, @one).nan?.should == true
# @one.send(@method, @nan).nan?.should == true
# @infinity.send(@method, @nan).nan?.should == true
# @nan.send(@method, @infinity).nan?.should == true
# end
# it "returns NaN if the dividend is Infinity" do
# @infinity.send(@method, @infinity).nan?.should == true
# @infinity.send(@method, @one).nan?.should == true
# @infinity.send(@method, @mixed).nan?.should == true
# @infinity.send(@method, @one_minus).nan?.should == true
# @infinity.send(@method, @frac_1).nan?.should == true
# @infinity_minus.send(@method, @infinity_minus).nan?.should == true
# @infinity_minus.send(@method, @one).nan?.should == true
# @infinity.send(@method, @infinity_minus).nan?.should == true
# @infinity_minus.send(@method, @infinity).nan?.should == true
# end
# ruby_version_is "" ... "1.9" do
# it "returns NaN if the divisor is Infinity" do
# @one.send(@method, @infinity).nan?.should == true
# @one.send(@method, @infinity_minus).nan?.should == true
# @frac_2.send(@method, @infinity_minus).nan?.should == true
# end
# end
# ruby_version_is "1.9" do
# it "returns the dividend if the divisor is Infinity" do
# @one.send(@method, @infinity).should == @one
# @one.send(@method, @infinity_minus).should == @one
# @frac_2.send(@method, @infinity_minus).should == @frac_2
# end
# end
# it "raises TypeError if the argument cannot be coerced to BigDecimal" do
# lambda {
# @one.send(@method, '2')
# }.should raise_error(TypeError)
# end
# ruby_version_is "" ... "1.9" do
# it "does NOT raise ZeroDivisionError if other is zero" do
# bd6543 = BigDecimal.new("6543.21")
# bd5667 = BigDecimal.new("5667.19")
# a = BigDecimal("1.0000000000000000000000000000000000000000005")
# b = BigDecimal("1.00000000000000000000000000000000000000000005")
# bd5667.send(@method, 0).nan?.should == true
# bd5667.send(@method, BigDecimal("0")).nan?.should == true
# @zero.send(@method, @zero).nan?.should == true
# end
# end
# ruby_version_is "1.9" do
# it "raises ZeroDivisionError if other is zero" do
# bd6543 = BigDecimal.new("6543.21")
# bd5667 = BigDecimal.new("5667.19")
# a = BigDecimal("1.0000000000000000000000000000000000000000005")
# b = BigDecimal("1.00000000000000000000000000000000000000000005")
# lambda { bd5667.send(@method, 0) }.should raise_error(ZeroDivisionError)
# lambda { bd5667.send(@method, BigDecimal("0")) }.should raise_error(ZeroDivisionError)
# lambda { @zero.send(@method, @zero) }.should raise_error(ZeroDivisionError)
# end
# end
end

View File

@@ -0,0 +1,26 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require File.expand_path('../shared/mult', __FILE__)
# require 'bigdecimal'
# describe "BigDecimal#*" do
# it_behaves_like :bigdecimal_mult, :*, []
# end
describe "BigDecimal#*" do
before do
# @e3_minus = BigDecimal("3E-20001")
# @e3_plus = BigDecimal("3E20001")
@e = BigDecimal("1.00000000000000000000123456789")
@one = BigDecimal("1")
end
it "multiply self with other" do
(@one * @one).should == @one
# (@e3_minus * @e3_plus).should == BigDecimal("9")
# Can't do this till we implement **
# (@e3_minus * @e3_minus).should == @e3_minus ** 2
# So let's rewrite it as:
# (@e3_minus * @e3_minus).should == BigDecimal("9E-40002")
(@e * @one).should == @e
end
end

View File

@@ -0,0 +1,50 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#+" do
before 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")
end
it "returns a + b" do
(@two + @one).should == @three
(@one + @two).should == @three
(@one + @one_minus).should == @zero
(@zero + @one).should == @one
(@ten + @one).should == @eleven
# (@frac_1 + @frac_2).should == BigDecimal("1.9E-99999")
# (@frac_2 + @frac_1).should == BigDecimal("1.9E-99999")
# (@frac_1 + @frac_1).should == BigDecimal("2E-99999")
# can't do it this way because * isn't implemented yet
# (@frac_1 + @frac_1).should == 2 * @frac_1
end
# it "returns NaN if NaN is involved" do
# (@one + @nan).nan?.should == true
# (@nan + @one).nan?.should == true
# end
# it "returns Infinity or -Infinity if these are involved" do
# (@zero + @infinity).should == @infinity
# (@frac_2 + @infinity).should == @infinity
# (@two + @infinity_minus).should == @infinity_minus
# end
# it "returns NaN if Infinity + (- Infinity)" do
# (@infinity + @infinity_minus).nan?.should == true
# end
end

View File

@@ -0,0 +1,84 @@
# require 'bigdecimal'
describe "BigDecimal#power" do
@method = :**
it "powers of self" do
e3_minus = BigDecimal("3E-21")
e3_minus_power_2 = BigDecimal("9E-42")
e3_plus = BigDecimal("3E21")
e2_plus = BigDecimal("2E41")
e5_minus = BigDecimal("5E-42")
e = BigDecimal("1.00000000000000000000123456789")
one = BigDecimal("1")
ten = BigDecimal("10")
# The tolerance is dependent upon the size of BASE_FIG
tolerance = BigDecimal("1E-70")
ten_powers = BigDecimal("1E100")
pi = BigDecimal("3.14159265358979")
e3_minus.send(@method, 2).should == e3_minus_power_2
e3_plus.send(@method, 0).should == 1
e3_minus.send(@method, 1).should == e3_minus
e2_plus.send(@method, -1).should == e5_minus
e2_plus.send(@method, -1).should == e5_minus.power(1)
(e2_plus.send(@method, -1) * e5_minus.send(@method, -1)).should == 1
e.send(@method, 2).should == e * e
# e.send(@method, -1).should be_close(one.div(e, 120), tolerance)
# ten.send(@method, 10000).should == ten_powers
# pi.send(@method, 10).should be_close(Math::PI ** 10, TOLERANCE)
end
it "powers of 1 equal 1" do
one = BigDecimal("1")
one.send(@method, 0).should == 1
one.send(@method, 1).should == 1
one.send(@method, 10).should == 1
one.send(@method, -10).should == 1
end
it "0 to power of 0 is 1" do
zero = BigDecimal("0")
zero.send(@method, 0).should == 1
end
# it "0 to powers < 0 is Infinity" do
# zero = BigDecimal("0")
# infinity = BigDecimal("Infinity")
# zero.send(@method, -10).should == infinity
# zero.send(@method, -1).should == infinity
# end
it "other powers of 0 are 0" do
zero = BigDecimal("0")
zero.send(@method, 1).should == 0
zero.send(@method, 10).should == 0
end
# it "returns NaN if self is NaN" do
# BigDecimal("NaN").send(@method, -5).nan?.should == true
# BigDecimal("NaN").send(@method, 5).nan?.should == true
# end
# ruby_version_is "" ... "1.8.8" do
# it "returns NaN if self is infinite" do
# BigDecimal("Infinity").send(@method, -5).nan?.should == true
# BigDecimal("-Infinity").send(@method, -5).nan?.should == true
# BigDecimal("Infinity").send(@method, 5).nan?.should == true
# BigDecimal("-Infinity").send(@method, 5).nan?.should == true
# end
# end
# ruby_version_is "1.8.8" do # this behavior may be backported to 1.8.7 [ruby-dev:40182]
# it "returns 0.0 if self is infinite and argument is negative" do
# BigDecimal("Infinity").send(@method, -5).should == 0
# BigDecimal("-Infinity").send(@method, -5).should == 0
# end
# it "returns infinite if self is infinite and argument is positive" do
# infinity = BigDecimal("Infinity")
# BigDecimal("Infinity").send(@method, 4).should == infinity
# BigDecimal("-Infinity").send(@method, 4).should == infinity
# BigDecimal("Infinity").send(@method, 5).should == infinity
# BigDecimal("-Infinity").send(@method, 5).should == -infinity
# end
# end
end

View File

@@ -0,0 +1,105 @@
# require 'bigdecimal'
# require 'rational'
describe "BigDecimal#quo" do
@method = :quo
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_plus = BigDecimal("+0")
@zero_minus = BigDecimal("-0")
@two = BigDecimal("2")
@three = BigDecimal("3")
@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")
@float = 1.48
@rational = Rational(17,3)
end
it "returns a / b" do
@two.send(@method, @one, *@object).should == @two
@one.send(@method, @two, *@object).should == BigDecimal("0.5")
# @eleven.send(@method, @three, *@object).should be_close(@three + (@two / @three), TOLERANCE)
@one.send(@method, @one_minus, *@object).should == @one_minus
@one_minus.send(@method, @one_minus, *@object).should == @one
# @frac_2.send(@method, @frac_1, *@object).should == BigDecimal("0.9")
# @frac_1.send(@method, @frac_1, *@object).should == @one
# @one.send(@method, BigDecimal('-2E5555'), *@object).should == BigDecimal('-0.5E-5555')
# @one.send(@method, BigDecimal('2E-5555'), *@object).should == BigDecimal('0.5E5555')
end
# it "returns 0 if divided by Infinity" do
# @zero.send(@method, @infinity, *@object).should == 0
# @frac_2.send(@method, @infinity, *@object).should == 0
# end
# it "returns (+|-) Infinity if (+|-) Infinity divided by one" do
# @infinity_minus.send(@method, @one, *@object).should == @infinity_minus
# @infinity.send(@method, @one, *@object).should == @infinity
# @infinity_minus.send(@method, @one_minus, *@object).should == @infinity
# end
# it "returns NaN if Infinity / ((+|-) Infinity)" do
# @infinity.send(@method, @infinity_minus, *@object).nan?.should == true
# @infinity_minus.send(@method, @infinity, *@object).nan?.should == true
# end
# it "returns (+|-) Infinity if divided by zero" do
# @one.send(@method, @zero, *@object).should == @infinity
# @one.send(@method, @zero_plus, *@object).should == @infinity
# @one.send(@method, @zero_minus, *@object).should == @infinity_minus
# end
it "returns NaN if zero is divided by zero" do
@zero.send(@method, @zero, *@object).nan?.should == true
@zero_minus.send(@method, @zero_plus, *@object).nan?.should == true
@zero_plus.send(@method, @zero_minus, *@object).nan?.should == true
end
# context "with a Float" do
# ruby_version_is "".."1.9" do
# it "returns a Float" do
# result = @eleven.send(@method, @float, *@object)
# result.should be_close(7.4324324324324325, TOLERANCE)
# result.kind_of?(Float).should == true
# end
# end
# ruby_version_is "2.0.0" do
# it "returns a BigDecimal" do
# result = @eleven.send(@method, @float, *@object)
# result.should be_close(7.4324324324324325, TOLERANCE)
# result.should be_an_instance_of(BigDecimal)
# end
# end
# end
# context "with a Rational" do
# ruby_version_is ""..."1.9" do
# it "returns a Float" do
# result = @eleven.send(@method, @rational, *@object)
# result.should be_close(1.94117647058824, TOLERANCE)
# result.kind_of?(Float).should == true
# end
# end
# ruby_version_is "1.9"..."2.0" do
# it "raises a TypeError" do
# lambda { @eleven.send(@method, @rational, *@object) }.should raise_error(TypeError)
# end
# end
# ruby_version_is "2.0.0" do
# it "returns a BigDecimal" do
# result = @eleven.send(@method, @rational, *@object)
# result.should be_close(1.94117647058824, TOLERANCE)
# result.kind_of?(BigDecimal).should == true
# end
# end
# end
end

View File

@@ -0,0 +1,194 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#round" do
before do
@one = BigDecimal("1")
@two = BigDecimal("2")
@three = BigDecimal("3")
@neg_one = BigDecimal("-1")
@neg_two = BigDecimal("-2")
@neg_three = BigDecimal("-3")
@p1_50 = BigDecimal("1.50")
@p1_51 = BigDecimal("1.51")
@p1_49 = BigDecimal("1.49")
@n1_50 = BigDecimal("-1.50")
@n1_51 = BigDecimal("-1.51")
@n1_49 = BigDecimal("-1.49")
@p2_50 = BigDecimal("2.50")
@p2_51 = BigDecimal("2.51")
@p2_49 = BigDecimal("2.49")
@n2_50 = BigDecimal("-2.50")
@n2_51 = BigDecimal("-2.51")
@n2_49 = BigDecimal("-2.49")
end
# after :each do
# BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
# end
it "uses default rounding method unless given" do
@p1_50.round(0).should == @two
@p1_51.round(0).should == @two
@p1_49.round(0).should == @one
@n1_50.round(0).should == @neg_two
@n1_51.round(0).should == @neg_two
@n1_49.round(0).should == @neg_one
@p2_50.round(0).should == @three
@p2_51.round(0).should == @three
@p2_49.round(0).should == @two
@n2_50.round(0).should == @neg_three
@n2_51.round(0).should == @neg_three
@n2_49.round(0).should == @neg_two
# BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
# @p1_50.round(0).should == @one
# @p1_51.round(0).should == @one
# @p1_49.round(0).should == @one
# @n1_50.round(0).should == @neg_one
# @n1_51.round(0).should == @neg_one
# @n1_49.round(0).should == @neg_one
# @p2_50.round(0).should == @two
# @p2_51.round(0).should == @two
# @p2_49.round(0).should == @two
# @n2_50.round(0).should == @neg_two
# @n2_51.round(0).should == @neg_two
# @n2_49.round(0).should == @neg_two
end
describe "BigDecimal::ROUND_UP" do
it "rounds values away from zero" do
@p1_50.round(0, BigDecimal::ROUND_UP).should == @two
@p1_51.round(0, BigDecimal::ROUND_UP).should == @two
@p1_49.round(0, BigDecimal::ROUND_UP).should == @two
# @n1_50.round(0, BigDecimal::ROUND_UP).should == @neg_two
# @n1_51.round(0, BigDecimal::ROUND_UP).should == @neg_two
# @n1_49.round(0, BigDecimal::ROUND_UP).should == @neg_two
@p2_50.round(0, BigDecimal::ROUND_UP).should == @three
@p2_51.round(0, BigDecimal::ROUND_UP).should == @three
@p2_49.round(0, BigDecimal::ROUND_UP).should == @three
# @n2_50.round(0, BigDecimal::ROUND_UP).should == @neg_three
# @n2_51.round(0, BigDecimal::ROUND_UP).should == @neg_three
# @n2_49.round(0, BigDecimal::ROUND_UP).should == @neg_three
end
end
describe "BigDecimal::ROUND_DOWN" do
it "rounds values towards zero" do
@p1_50.round(0, BigDecimal::ROUND_DOWN).should == @one
@p1_51.round(0, BigDecimal::ROUND_DOWN).should == @one
@p1_49.round(0, BigDecimal::ROUND_DOWN).should == @one
# @n1_50.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
# @n1_51.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
# @n1_49.round(0, BigDecimal::ROUND_DOWN).should == @neg_one
@p2_50.round(0, BigDecimal::ROUND_DOWN).should == @two
@p2_51.round(0, BigDecimal::ROUND_DOWN).should == @two
@p2_49.round(0, BigDecimal::ROUND_DOWN).should == @two
# @n2_50.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
# @n2_51.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
# @n2_49.round(0, BigDecimal::ROUND_DOWN).should == @neg_two
end
end
describe "BigDecimal::ROUND_HALF_UP" do
it "rounds values >= 5 up, otherwise down" do
@p1_50.round(0, BigDecimal::ROUND_HALF_UP).should == @two
@p1_51.round(0, BigDecimal::ROUND_HALF_UP).should == @two
@p1_49.round(0, BigDecimal::ROUND_HALF_UP).should == @one
# @n1_50.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
# @n1_51.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
# @n1_49.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_one
@p2_50.round(0, BigDecimal::ROUND_HALF_UP).should == @three
@p2_51.round(0, BigDecimal::ROUND_HALF_UP).should == @three
@p2_49.round(0, BigDecimal::ROUND_HALF_UP).should == @two
# @n2_50.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_three
# @n2_51.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_three
# @n2_49.round(0, BigDecimal::ROUND_HALF_UP).should == @neg_two
end
end
# ruby_bug "redmine:3803/4567", "1.9.2" do
# describe "BigDecimal::ROUND_HALF_DOWN" do
# it "rounds values > 5 up, otherwise down" do
# @p1_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @one
# @p1_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
# @p1_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @one
# @n1_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_one
# @n1_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
# @n1_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_one
# @p2_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
# @p2_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @three
# @p2_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @two
# @n2_50.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
# @n2_51.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_three
# @n2_49.round(0, BigDecimal::ROUND_HALF_DOWN).should == @neg_two
# end
# end
# end
# describe "BigDecimal::ROUND_CEILING" do
# it "rounds values towards +infinity" do
# @p1_50.round(0, BigDecimal::ROUND_CEILING).should == @two
# @p1_51.round(0, BigDecimal::ROUND_CEILING).should == @two
# @p1_49.round(0, BigDecimal::ROUND_CEILING).should == @two
# @n1_50.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
# @n1_51.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
# @n1_49.round(0, BigDecimal::ROUND_CEILING).should == @neg_one
# @p2_50.round(0, BigDecimal::ROUND_CEILING).should == @three
# @p2_51.round(0, BigDecimal::ROUND_CEILING).should == @three
# @p2_49.round(0, BigDecimal::ROUND_CEILING).should == @three
# @n2_50.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
# @n2_51.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
# @n2_49.round(0, BigDecimal::ROUND_CEILING).should == @neg_two
# end
# end
# describe "BigDecimal::ROUND_FLOOR" do
# it "rounds values towards -infinity" do
# @p1_50.round(0, BigDecimal::ROUND_FLOOR).should == @one
# @p1_51.round(0, BigDecimal::ROUND_FLOOR).should == @one
# @p1_49.round(0, BigDecimal::ROUND_FLOOR).should == @one
# @n1_50.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
# @n1_51.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
# @n1_49.round(0, BigDecimal::ROUND_FLOOR).should == @neg_two
# @p2_50.round(0, BigDecimal::ROUND_FLOOR).should == @two
# @p2_51.round(0, BigDecimal::ROUND_FLOOR).should == @two
# @p2_49.round(0, BigDecimal::ROUND_FLOOR).should == @two
# @n2_50.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
# @n2_51.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
# @n2_49.round(0, BigDecimal::ROUND_FLOOR).should == @neg_three
# end
# end
# ruby_bug "redmine:3803/4567", "1.9.2" do
# describe "BigDecimal::ROUND_HALF_EVEN" do
# it "rounds values > 5 up, < 5 down and == 5 towards even neighbor" do
# @p1_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
# @p1_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
# @p1_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @one
# @n1_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
# @n1_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
# @n1_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_one
# @p2_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
# @p2_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @three
# @p2_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @two
# @n2_50.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
# @n2_51.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_three
# @n2_49.round(0, BigDecimal::ROUND_HALF_EVEN).should == @neg_two
# end
# end
# end
end

View File

@@ -0,0 +1,55 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#to_f" do
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
@two = BigDecimal("2")
@three = BigDecimal("3")
@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")
@vals = [@one, @zero, @two, @three, @frac_1, @frac_2]
@spec_vals = [@zero_pos, @zero_neg, @nan, @infinity, @infinity_minus]
end
it "returns number of type float" do
BigDecimal("3.14159").to_f.class.should == Float
@vals.each { |val| val.to_f.class.should == Float }
@spec_vals.each { |val| val.to_f.class.should == Float }
end
it "Floating point rounding occurs" do
# bigdec = BigDecimal("3.141592653589793238462643383279502884197169399375")
# bigdec.to_f.should be_close(3.14159265358979, TOLERANCE)
@one.to_f.should == 1.0
@two.to_f.should == 2.0
# @three.to_f.should be_close(3.0, TOLERANCE)
@one_minus.to_f.should == -1.0
# regression test for [ruby-talk:338957]
BigDecimal("10.03").to_f.should == 10.03
end
it "properly handles special values" do
@zero.to_f.should == 0
@zero.to_f.to_s.should == "0.0"
@nan.to_f.nan?.should == true
# @infinity.to_f.infinite?.should == 1
# @infinity_minus.to_f.infinite?.should == -1
end
it "remembers negative zero when converted to float" do
@zero_neg.to_f.should == 0
# @zero_neg.to_f.to_s.should == "-0.0"
end
end

View File

@@ -0,0 +1,28 @@
# require 'bigdecimal'
describe "BigDecimal#to_i" do
@method = :to_i
# ruby_version_is "" ... "1.9" do
# ruby_bug "fixed_in_ruby_1_8_7@25799", "1.8.7.202" do
# it "returns nil if BigDecimal is infinity or NaN" do
# BigDecimal("Infinity").send(@method).should == nil
# BigDecimal("NaN").send(@method).should == nil
# end
# end
# end
# ruby_version_is "1.9" do
# it "raises FloatDomainError if BigDecimal is infinity or NaN" do
# lambda { BigDecimal("Infinity").send(@method) }.should raise_error(FloatDomainError)
# lambda { BigDecimal("NaN").send(@method) }.should raise_error(FloatDomainError)
# end
# end
it "returns Integer or Bignum otherwise" do
# BigDecimal("3E-20001").send(@method).should == 0
# BigDecimal("2E4000").send(@method).should == 2 * 10 ** 4000
BigDecimal("2").send(@method).should == 2
# BigDecimal("2E10").send(@method).should == 20000000000
BigDecimal("3.14159").send(@method).should == 3
end
end

View File

@@ -0,0 +1,28 @@
# require 'bigdecimal'
describe "BigDecimal#to_int" do
@method = :to_int
# ruby_version_is "" ... "1.9" do
# ruby_bug "fixed_in_ruby_1_8_7@25799", "1.8.7.202" do
# it "returns nil if BigDecimal is infinity or NaN" do
# BigDecimal("Infinity").send(@method).should == nil
# BigDecimal("NaN").send(@method).should == nil
# end
# end
# end
# ruby_version_is "1.9" do
# it "raises FloatDomainError if BigDecimal is infinity or NaN" do
# lambda { BigDecimal("Infinity").send(@method) }.should raise_error(FloatDomainError)
# lambda { BigDecimal("NaN").send(@method) }.should raise_error(FloatDomainError)
# end
# end
it "returns Integer or Bignum otherwise" do
# BigDecimal("3E-20001").send(@method).should == 0
# BigDecimal("2E4000").send(@method).should == 2 * 10 ** 4000
BigDecimal("2").send(@method).should == 2
# BigDecimal("2E10").send(@method).should == 20000000000
BigDecimal("3.14159").send(@method).should == 3
end
end

View File

@@ -0,0 +1,72 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#to_s" do
before do
@bigdec_str = "3.14159265358979323846264338327950288419716939937"
@bigneg_str = "-3.1415926535897932384626433832795028841971693993"
@bigdec = BigDecimal(@bigdec_str)
@bigneg = BigDecimal(@bigneg_str)
end
it "returns a string" do
@bigdec.to_s.kind_of?(String).should == true
@bigneg.to_s.kind_of?(String).should == true
end
# it "the default format looks like 0.xxxxEnn" do
# @bigdec.to_s.should =~ /^0\.[0-9]*E[0-9]*$/
# end
# it "takes an optional argument" do
# lambda {@bigdec.to_s("F")}.should_not raise_error()
# end
# it "starts with + if + is supplied and value is positive" do
# @bigdec.to_s("+").should =~ /^\+.*/
# @bigneg.to_s("+").should_not =~ /^\+.*/
# end
it "inserts a space every n chars, if integer n is supplied" do
# str =\
# "0.314 159 265 358 979 323 846 264 338 327 950 288 419 716 939 937E1"
# @bigdec.to_s(3).should == str
# str1 = '-123.45678 90123 45678 9'
# BigDecimal.new("-123.45678901234567890").to_s('5F').should == str1
# trailing zeroes removed
# BigDecimal.new("1.00000000000").to_s('1F').should == "1.0"
# 0 is treated as no spaces
BigDecimal.new("1.2345").to_s('0F').should == "1.2345"
end
# it "can return a leading space for values > 0" do
# @bigdec.to_s(" F").should =~ /\ .*/
# @bigneg.to_s(" F").should_not =~ /\ .*/
# end
# it "removes trailing spaces in floating point notation" do
# BigDecimal.new('-123.45678901234567890').to_s('F').should == "-123.4567890123456789"
# BigDecimal.new('1.2500').to_s('F').should == "1.25"
# BigDecimal.new('0000.00000').to_s('F').should == "0.0"
# BigDecimal.new('-00.000010000').to_s('F').should == "-0.00001"
# BigDecimal.new("5.00000E-2").to_s("F").should == "0.05"
# BigDecimal.new("500000").to_s("F").should == "500000.0"
# BigDecimal.new("5E2").to_s("F").should == "500.0"
# BigDecimal.new("-5E100").to_s("F").should == "-5" + "0" * 100 + ".0"
# end
# it "can use engineering notation" do
# @bigdec.to_s("E").should =~ /^0\.[0-9]*E[0-9]*$/
# end
# it "can use conventional floating point notation" do
# @bigdec.to_s("F").should == @bigdec_str
# @bigneg.to_s("F").should == @bigneg_str
# str2 = "+123.45678901 23456789"
# BigDecimal.new('123.45678901234567890').to_s('+8F').should == str2
# end
end

View File

@@ -0,0 +1,57 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#-@" do
before do
@one = BigDecimal("1")
@zero = BigDecimal("0")
@zero_pos = BigDecimal("+0")
@zero_neg = BigDecimal("-0")
@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")
# @big = BigDecimal("333E99999")
# @big_neg = BigDecimal("-333E99999")
@values = [@one, @zero, @zero_pos, @zero_neg, @one_minus]
end
it "negates self" do
@one.send(:-@).should == @one_minus
@one_minus.send(:-@).should == @one
# @frac_1.send(:-@).should == BigDecimal("-1E-99999")
# @frac_2.send(:-@).should == BigDecimal("-0.9E-99999")
# @big.send(:-@).should == @big_neg
# @big_neg.send(:-@).should == @big
BigDecimal("2.221").send(:-@).should == BigDecimal("-2.221")
# BigDecimal("2E10000").send(:-@).should == BigDecimal("-2E10000")
some_number = BigDecimal("2455999221.5512")
some_number_neg = BigDecimal("-2455999221.5512")
some_number.send(:-@).should == some_number_neg
(-BigDecimal("-5.5")).should == BigDecimal("5.5")
another_number = BigDecimal("-8.551551551551551551")
another_number_pos = BigDecimal("8.551551551551551551")
another_number.send(:-@).should == another_number_pos
@values.each do |val|
(val.send(:-@).send(:-@)).should == val
end
end
it "properly handles special values" do
# @infinity.send(:-@).should == @infinity_minus
# @infinity_minus.send(:-@).should == @infinity
# @infinity.send(:-@).infinite?.should == -1
# @infinity_minus.send(:-@).infinite?.should == 1
@zero.send(:-@).should == @zero
# @zero.send(:-@).sign.should == -1
@zero_pos.send(:-@).should == @zero
# @zero_pos.send(:-@).sign.should == -1
@zero_neg.send(:-@).should == @zero
# @zero_neg.send(:-@).sign.should == 1
# @nan.send(:-@).nan?.should == true
end
end

View File

@@ -0,0 +1,17 @@
# require File.expand_path('../../../spec_helper', __FILE__)
# require 'bigdecimal'
describe "BigDecimal#+@" do
it "returns the same value with same sign (twos complement)" do
first = BigDecimal("34.56")
first.send(:+@).should == first
second = BigDecimal("-34.56")
second.send(:+@).should == second
third = BigDecimal("0.0")
third.send(:+@).should == third
fourth = BigDecimal("2E1000000")
fourth.send(:+@).should == fourth
fifth = BigDecimal("123456789E-1000000")
fifth.send(:+@).should == fifth
end
end