it “should get right settlement percent” do
contract = Contract.new
contract.settlement_percent = 1.1 / 100.0
contract.settlement_percent.to_f.should == 0.011
contract.settlement_percent.to_s.should == “0.011”
end
but test result is :
Failure/Error: contract.settlement_percent.to_f.should == 0.011
expected: 0.011,
got: 0.011000000000000001 (using ==)
# ./spec/models/contract_spec.rb:16:in `block (3 levels) in <top
(required)>’
Quoting 蕲春人 [email protected]:
expected: 0.011,
got: 0.011000000000000001 (using ==)
# ./spec/models/contract_spec.rb:16:in `block (3 levels) in <top
(required)>’
Your model of floating point is incorrect. Exact equality with floating
point
is rarely a good idea. Most modern computers use the IEEE floating
point
format and arithmetic is done in base 2. There are many base 10
fractions
that do not have exact base 2 representations. And once you start doing
calculations, they diverge even further.
There are several ways around this. The simplest is:
contract.settlement_percent.round_with_precision(5).should == 0.011
(’%0.3f’ % contract.settlement_percent).should == ‘0.011’
If you have legal requirements (e.g. SEC regulations) on how arithmetic
works,
you had better write your own class. Depending on floating point on
arbitrary
architectures to behave in a certain way is inviting trouble.
Jeffrey
Jeffrey L. Taylor wrote in post #966404:
Quoting 蕲春人 [email protected]:
expected: 0.011,
got: 0.011000000000000001 (using ==)
# ./spec/models/contract_spec.rb:16:in `block (3 levels) in <top
(required)>’
Your model of floating point is incorrect. Exact equality with floating
point
is rarely a good idea. Most modern computers use the IEEE floating
point
format and arithmetic is done in base 2. There are many base 10
fractions
that do not have exact base 2 representations. And once you start doing
calculations, they diverge even further.
There are several ways around this. The simplest is:
contract.settlement_percent.round_with_precision(5).should == 0.011
(’%0.3f’ % contract.settlement_percent).should == ‘0.011’
Actually, the simplest thing to do is to just avoid Float for math
altogether. Use BigDecimal and Rational instead.
Best,
Marnen Laibow-Koser
http://www.marnen.org
[email protected]
Sent from my iPhone