# comparing floats

10 messages
Open this post in threaded view
|

## comparing floats

 Hi all, i want to compare two small arbitrary floats such as: -3.81964e-13 = -3.55671e-13  --> false but I only want the answer to be false if the difference between the floats is too large. So rather than taking the difference and comparing that to my limit, I want to round or truncate the floats to:   -3.0e-13 = -3.0e-13 --> true  OR -4.0e-13 = -4.0e-13 --> true I need a way to consistently tranform the numbers without retaining the actual numbers. a := (-3.81964e-13 asFixedPoint: 13) --> -0.0000000000004s b := (-3.55671e-13 asFixedPoint: 13) --> -0.0000000000004s but (a = b) --> false, because it is only changing the representation, not the object itself. So I am having some trouble wrapping my head around how to permanently change the number or how to compare the representations only or how to create a new number with less precision. Any help would be appreciated. thanks Adam _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Open this post in threaded view
|

## Re: comparing floats

 On 2014-04-25 2:14 PM, Dennis Smith wrote: > Instead of rounding or truncating which may or may not do exactly what > you want, why not look at the difference ... > >     diff := (a - b) abs. > > Now you can check 'diff' either for some absolute max difference, or > as a percentage of one of the values ... > >     ^diff < (a abs * 0.1) > > > On 2014-04-25 2:03 PM, Adam Crumpton wrote: >> Hi all, >> >> i want to compare two small arbitrary floats such as: >> >> -3.81964e-13 = -3.55671e-13  --> false >> >> but I only want the answer to be false if the difference between the >> floats is too large. >> >> So rather than taking the difference and comparing that to my limit, >> I want to round or truncate the floats to: >> >>  -3.0e-13 = -3.0e-13 --> true  OR >> -4.0e-13 = -4.0e-13 --> true >> >> I need a way to consistently tranform the numbers without retaining >> the actual numbers. >> >> a := (-3.81964e-13 asFixedPoint: 13) --> -0.0000000000004s >> b := (-3.55671e-13 asFixedPoint: 13) --> -0.0000000000004s >> >> but (a = b) --> false, because it is only changing the >> representation, not the object itself. >> >> So I am having some trouble wrapping my head around how to >> permanently change the number or how to compare the representations >> only or how to create a new number with less precision. Any help >> would be appreciated. >> >> thanks >> Adam >> _______________________________________________ >> vwnc mailing list >> [hidden email] >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc> -- Dennis Smith Cherniak Software Development Corporation Phone  416.798.7948 ext 314 Email  [hidden email] _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Open this post in threaded view
|

## Re: comparing floats

 In reply to this post by Adam Crumpton Instead of rounding or truncating which may or may not do exactly what you want, why not look at the difference ...      diff := (a - b) abs. Now you can check 'diff' either for some absolute max difference, or as a percentage of one of the values ...      ^diff < (a abs * 0.1) On 2014-04-25 2:03 PM, Adam Crumpton wrote: > Hi all, > > i want to compare two small arbitrary floats such as: > > -3.81964e-13 = -3.55671e-13  --> false > > but I only want the answer to be false if the difference between the > floats is too large. > > So rather than taking the difference and comparing that to my limit, I > want to round or truncate the floats to: > >  -3.0e-13 = -3.0e-13 --> true  OR > -4.0e-13 = -4.0e-13 --> true > > I need a way to consistently tranform the numbers without retaining > the actual numbers. > > a := (-3.81964e-13 asFixedPoint: 13) --> -0.0000000000004s > b := (-3.55671e-13 asFixedPoint: 13) --> -0.0000000000004s > > but (a = b) --> false, because it is only changing the representation, > not the object itself. > > So I am having some trouble wrapping my head around how to permanently > change the number or how to compare the representations only or how to > create a new number with less precision. Any help would be appreciated. > > thanks > Adam > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc-- Dennis Smith Cherniak Software Development Corporation Phone  416.798.7948 ext 314 Email  [hidden email] _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Open this post in threaded view
|

## transforming floats [was: comparing floats]

 In reply to this post by Adam Crumpton That was my first idea, but I don't know what the ideal max difference should be and it really doesn't give me what I want.  for now, I am using the absolute value of the exponent as the length of my FixedPoint, printing the result, and then creating a Float from that string. Then I am adding all of the values to a Bag and getting the tallies. And on top of that there are many such bags that need to be compared with each other. So I was hoping that I was ignorant of method of round or truncating, that was smalltalkish and elegant, because if the two numbers are similar enough, then I need to keep them but only at their generalized precision. I need to make them truly equal. So to recap: I want to tranform a small float into a less small float (-3.81964e-13 --> -4.0e-13) and I want to keep the less small float for tallying and comparing with other less small floats. And I want it to be elegant. thanks, Adam On 4/25/14, 1:14 PM, Dennis Smith wrote: > Instead of rounding or truncating which may or may not do exactly what > you want, why not look at the difference ... > >     diff := (a - b) abs. > > Now you can check 'diff' either for some absolute max difference, or > as a percentage of one of the values ... > >     ^diff < (a abs * 0.1) > > > On 2014-04-25 2:03 PM, Adam Crumpton wrote: >> Hi all, >> >> i want to compare two small arbitrary floats such as: >> >> -3.81964e-13 = -3.55671e-13  --> false >> >> but I only want the answer to be false if the difference between the >> floats is too large. >> >> So rather than taking the difference and comparing that to my limit, >> I want to round or truncate the floats to: >> >>  -3.0e-13 = -3.0e-13 --> true  OR >> -4.0e-13 = -4.0e-13 --> true >> >> I need a way to consistently tranform the numbers without retaining >> the actual numbers. >> >> a := (-3.81964e-13 asFixedPoint: 13) --> -0.0000000000004s >> b := (-3.55671e-13 asFixedPoint: 13) --> -0.0000000000004s >> >> but (a = b) --> false, because it is only changing the >> representation, not the object itself. >> >> So I am having some trouble wrapping my head around how to >> permanently change the number or how to compare the representations >> only or how to create a new number with less precision. Any help >> would be appreciated. >> >> thanks >> Adam >> _______________________________________________ >> vwnc mailing list >> [hidden email] >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc> _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Open this post in threaded view
|

## Re: transforming floats [was: comparing floats]

 Adam, You're bumping up against a basic characteristic of floating point numbers, independent of Smalltalk. A good discussion of this can be found here: http://parashift.com/c++-faq/floating-point-arith.html On 4/25/14, 1:23 PM, Adam Crumpton wrote: That was my first idea, but I don't know what the ideal max difference should be and it really doesn't give me what I want.  for now, I am using the absolute value of the exponent as the length of my FixedPoint, printing the result, and then creating a Float from that string. Then I am adding all of the values to a Bag and getting the tallies. And on top of that there are many such bags that need to be compared with each other. So I was hoping that I was ignorant of method of round or truncating, that was smalltalkish and elegant, because if the two numbers are similar enough, then I need to keep them but only at their generalized precision. I need to make them truly equal. So to recap: I want to tranform a small float into a less small float (-3.81964e-13 --> -4.0e-13) and I want to keep the less small float for tallying and comparing with other less small floats. And I want it to be elegant. thanks, Adam On 4/25/14, 1:14 PM, Dennis Smith wrote: Instead of rounding or truncating which may or may not do exactly what you want, why not look at the difference ...     diff := (a - b) abs. Now you can check 'diff' either for some absolute max difference, or as a percentage of one of the values ...     ^diff < (a abs * 0.1) On 2014-04-25 2:03 PM, Adam Crumpton wrote: Hi all, i want to compare two small arbitrary floats such as: -3.81964e-13 = -3.55671e-13  --> false but I only want the answer to be false if the difference between the floats is too large. So rather than taking the difference and comparing that to my limit, I want to round or truncate the floats to:  -3.0e-13 = -3.0e-13 --> true  OR -4.0e-13 = -4.0e-13 --> true I need a way to consistently tranform the numbers without retaining the actual numbers. a := (-3.81964e-13 asFixedPoint: 13) --> -0.0000000000004s b := (-3.55671e-13 asFixedPoint: 13) --> -0.0000000000004s but (a = b) --> false, because it is only changing the representation, not the object itself. So I am having some trouble wrapping my head around how to permanently change the number or how to compare the representations only or how to create a new number with less precision. Any help would be appreciated. thanks Adam _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Open this post in threaded view
|

## Re: transforming floats [was: comparing floats]

Open this post in threaded view
|

## Re: transforming floats [was: comparing floats]

Open this post in threaded view
|

## Re: transforming floats [was: comparing floats]

 In reply to this post by Adam Crumpton On 04/25/2014 12:23 PM, Adam Crumpton wrote: > I want to tranform a small float into a less small float (-3.81964e-13 > --> -4.0e-13) and I want to keep the less small float for tallying and > comparing with other less small floats. Keep in mind that floats are represented in binary, and that numbers such as -4.0e-13 that look "simple" in decimal notation are not exactly representable as floats. If you want to round or truncate a float for comparison, you might want to do the rounding or truncating in binary to some fixed number of bits of precision. For instance, to truncate a normal 32-bit Float on a little-endian platform to 16 significant bits (reducing the precision by 8 bits): | truncatedFloat | truncatedFloat := inputFloat copy. truncatedFloat   basicAt: 1 put: 0 > And I want it to be elegant. Well, I can't claim the above is particularly elegant, but it does seem simpler than what you are currently doing. One way to increase elegance might be to use a subclass of Bag (ApproximateFloatBag, perhaps) that knows to truncate each instance of Float that is added to it. Regards, -Martin _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc