Live data from Hacker News

Comparing Floating-Point Numbers Is Tricky

bitbashing.io

11–20 of 45 posts

Re: Comparing Floating-Point Numbers Is Tricky

#11
post #5

Can someone explain why float is "better" than numeric in this example? pg1:joel=#* select 1/7::numeric 7; ?column? ------------------------ 0.99999999999999999998 (1 row) pg1:joel=# select 1/7::float*7; ?column? ---------- 1 (1 row)

Floating point math is a bit fuzzy, so many languages will round to the nearest integer if the float is within a certain margin. Numeric types are meant to be exact, so they will be represented as an exact value.

Floating-point math is carefully-defined. There are multiple independently-developed but interoperable implementations and an IEEE standard that talks in detail about how floating-point math is supposed to work. It's not "a bit fuzzy."

Re: Comparing Floating-Point Numbers Is Tricky

#12
post #4

The operator overlooks my pet peeve when it comes to comparing floating-point numbers: in C++ the "standard associative containers" (std::set and std::map) are based on ordering using an less-than relationship which must be a "strict weak ordering". Many times, the methods suggested for comparing floating point types do not satisfy the requirements of "strict weak ordering", and in this case the C++ standard says you…

This is actually caused by the use of the x87 80 bit floating point registers. (Infamous GCC bug #323)

When the float is first inserted into the set/map it has 80 bit precision, but that gets truncated to float or double precision during the store. This breaks the ordering as you are saying, but it's not an inherent flaw with floats as such.

The problem goes away if you compile with -mfpmath=sse because then the math will be performed in the same precision as the storage format.

Bug #323 is responsible for a huge amount of mistrust of floats that they don't deserve. Other compilers don't have this problem because they truncate the floats before any comparison.

Re: Comparing Floating-Point Numbers Is Tricky

#14
post #4

The operator overlooks my pet peeve when it comes to comparing floating-point numbers: in C++ the "standard associative containers" (std::set and std::map) are based on ordering using an less-than relationship which must be a "strict weak ordering". Many times, the methods suggested for comparing floating point types do not satisfy the requirements of "strict weak ordering", and in this case the C++ standard says you…

[deleted]

Re: Comparing Floating-Point Numbers Is Tricky

#16
post #4

The operator overlooks my pet peeve when it comes to comparing floating-point numbers: in C++ the "standard associative containers" (std::set and std::map) are based on ordering using an less-than relationship which must be a "strict weak ordering". Many times, the methods suggested for comparing floating point types do not satisfy the requirements of "strict weak ordering", and in this case the C++ standard says you…

This is actually caused by the use of the x87 80 bit floating point registers. (Infamous GCC bug #323) When the float is first inserted into the set/map it has 80 bit precision, but that gets truncated to float or double precision during the store. This breaks the ordering as you are saying, but it's not an inherent flaw with floats as such. The problem goes away if you compile with -mfpmath=sse because then the math…

Yes, though I'm specifically talking about when you decide to define a 'bool less_than(double, double)' that uses some kind of fuzzy comparison approach internally. This can affect any platform, not just one with the "bug #323" behavior in it.

Re: Comparing Floating-Point Numbers Is Tricky

#17
post #9
post #6

Earlier quoted context omitted.

Is it better now?

I still see it in a couple of places where code-formatted text is inline with regular text, for example "relative_difference." The code blocks themselves look good.

Hopefully that fixes it. Sorry I suck at CSS.

Re: Comparing Floating-Point Numbers Is Tricky

#19
post #5

Earlier quoted context omitted.

Floating point math is a bit fuzzy, so many languages will round to the nearest integer if the float is within a certain margin. Numeric types are meant to be exact, so they will be represented as an exact value.

Floating-point math is carefully-defined. There are multiple independently-developed but interoperable implementations and an IEEE standard that talks in detail about how floating-point math is supposed to work. It's not "a bit fuzzy."

It most certainly is a bit fuzzy. For a fun critique of the newer IEEE standard by a real FP expert, see:

http://www.russinoff.com/papers/ieee.pdf

For something more concrete, consider Section 8, "Variations Allowed by the IEEE Floating-Point Standard", of the TestFloat tool for testing floating point implementations for IEEE compliance:

http://www.jhauser.us/arithmetic/TestFloat-3c/doc/TestFloat-...

And of course, many arithmetic operations (e.g., trig functions) aren't even covered by the standard, which occasionally provokes consternation like this...

https://forums.theregister.co.uk/forum/1/2014/10/10/intel_un...

Re: Comparing Floating-Point Numbers Is Tricky

#20
post #16

Earlier quoted context omitted.

This is actually caused by the use of the x87 80 bit floating point registers. (Infamous GCC bug #323) When the float is first inserted into the set/map it has 80 bit precision, but that gets truncated to float or double precision during the store. This breaks the ordering as you are saying, but it's not an inherent flaw with floats as such. The problem goes away if you compile with -mfpmath=sse because then the math…

Yes, though I'm specifically talking about when you decide to define a 'bool less_than(double, double)' that uses some kind of fuzzy comparison approach internally. This can affect any platform, not just one with the "bug #323" behavior in it.

You don't need (and shouldn't do) any kind of fuzzy comparison for less than for floats.
Post reply on HN