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)>'' -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Quoting 蕲春人 <whyruby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> 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)>'' >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 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Jeffrey L. Taylor wrote in post #966404:> Quoting 蕲春人 <whyruby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>: >> 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 marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org Sent from my iPhone -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.