Evaluate:
659.05+20.9 = 679.95 returns false ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) returns true |
Sorry, this is D5.1.1 Pro (haven't tried in other versions)
"Ted Bracht" <[hidden email]> wrote in message news:3f4e82a7$[hidden email]... > Evaluate: > > 659.05+20.9 = 679.95 > > returns false > > ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) > > returns true > > > |
In reply to this post by Ted Bracht-3
Ted,
> Evaluate: > > 659.05+20.9 = 679.95 > > returns false > > ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) > > returns true But look at 659.05+20.9 - 679.95. Floats are not precise representations, so a relative error or other range-based test is usually necessary. Also, see #asTrueFraction. There could be a defect at work here, but I doubt it. I'm acutually more interested in why the rounded case works :) Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Ted Bracht-3
Ted
I think that a little digging through newsgroups will turn up many such Float and floating point arithmetic "errors" being reported. All software float objects are an approximation of the mathematical real number, with the precision of the software float determined by the number of bytes used to represent the number. Try inspecting the lhs and rhs of the expression, and (at least in VW ) and the values assigned to each byte. Usually the least significant byte value will be different. So if you are using Floats to represent a Currency amount - be aware of these problems. VW has an ~= message that does answer true, 659.05d + 20.9d ~= 679.95d --> true In VW I have to force the use of double precision floats to reproduce the anomalie. On Thu, 28 Aug 2003 23:06:41 +0100, Ted Bracht <[hidden email]> wrote: > Sorry, this is D5.1.1 Pro (haven't tried in other versions) > > > "Ted Bracht" <[hidden email]> wrote in message > news:3f4e82a7$[hidden email]... >> Evaluate: >> >> 659.05+20.9 = 679.95 >> >> returns false >> >> ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) >> >> returns true >> >> >> > > > |
In reply to this post by Ted Bracht-3
Hi Ted,
You might try using #equals: 659.05+20.9 equals: 679.95 returns true. btw, 659.05+20.9 - 679.95 returns -1.13686837721616e-013 which makes sense as per the other posts on this. Gotta love them floats, eh? *ugh* -- Louis "Ted Bracht" <[hidden email]> wrote in message news:3f4e82a7$[hidden email]... > Evaluate: > > 659.05+20.9 = 679.95 > > returns false > > ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) > > returns true > > > |
In reply to this post by Bill Schwab-2
"Bill Schwab" <[hidden email]> wrote in message
news:bim2it$av5iq$[hidden email]... > Ted, > > > Evaluate: > > > > 659.05+20.9 = 679.95 > > > > returns false > > > > ((659.05+20.9) roundTo: 0.01) = (679.95 roundTo: 0.01) > > > > returns true > > But look at 659.05+20.9 - 679.95. Floats are not precise representations, > so a relative error or other range-based test is usually necessary. Also, > see #asTrueFraction. > > There could be a defect at work here, but I doubt it. I'm acutually more > interested in why the rounded case works :) > I think this should make that clearer: #(659.05 20.9 679.95 ##(659.05 + 20.9) ##((659.05 + 20.9) roundTo: 0.01)) do: [:each | each printOn: Transcript decimalPlaces: 15. Transcript cr] Regards Blair |
In reply to this post by estow
Edward
You wrote in message news:[hidden email]... > ... > VW has an ~= message that does answer true, > > 659.05d + 20.9d ~= 679.95d --> true > ... Careful, the meaning of #~= in Smalltalk is not "approximately equal" as you might expect, but "not equal". In this it will give the "right" result :-). AFAIK VW does not provide a method to compare whether to floats are equal to a specified precision. A handy method for doing so is: compare: x to: y epsilon: epsilon "Compare that the two <Float> values are equivalent to within the specified <Float> difference." | max | ^(max := x abs max: y abs) <= epsilon or: [(x - y) abs < (epsilon * max)] We use this method in our SUnit test hierarchy as it allows one to specify the maximum "error". It should work correctly regardless of the magnitudes involved; the naiive implementation '(x - y) < epsilon' gives the wrong result for large floats since it takes no account of the precision limits of the representation. A handy shortcut for this is the #equals: message on Float, which uses a precision of 1e-9, which is appropriate for many uses. It would be nice to have a standard binary selector for #equals: in Smalltalk (and a standard value for the epsilon it uses for single and double precision floats), but unfortunately the obvious choices using the '~' character are either in use or likely to be confused with #~= (not equal) and #~~ (not identical). Regards Blair |
In reply to this post by Ted Bracht-3
There is a nice book covering the whole issue and in addition containig a
lot of nice numerical stuff. http://www.amazon.com/exec/obidos/tg/detail/-/1558606793/qid=1062160102/sr=8 -1/ref=sr_8_1/002-0279682-7698445?v=glance&s=books&n=507846 It also contains a library that is already ported to Dolphin. http://sourceforge.net/projects/dhbnumerics/ A Number>>equalsTo: (comparing taking the systems numerical precision into account) and Number>>relativelyEqualsTo:upTo: as proposed in this thread is also included. Ciao ...Jochen |
In reply to this post by Blair McGlashan
Blair,
> > There could be a defect at work here, but I doubt it. I'm acutually more > > interested in why the rounded case works :) > > > > I think this should make that clearer: > > #(659.05 20.9 679.95 ##(659.05 + 20.9) ##((659.05 + 20.9) roundTo: 0.01)) > do: [:each | each printOn: Transcript decimalPlaces: 15. Transcript cr] That does help. Should this perhaps be the default #printOn: (developer-specific) for floats?? Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Blair McGlashan
On Fri, 29 Aug 2003 09:47:52 +0100, Blair McGlashan <[hidden email]>
wrote: > Edward > > You wrote in message news:[hidden email]... >> ... >> VW has an ~= message that does answer true, >> >> 659.05d + 20.9d ~= 679.95d --> true >> ... > > Careful, the meaning of #~= in Smalltalk is not "approximately equal" as > you > might expect, but "not equal". In this it will give the "right" result :-) > > Doh "Expressing frustration at the realization ...that one has just said or done something foolish." OED http://dictionary.oed.com/ [Remainder of message snipped] |
Free forum by Nabble | Edit this page |