Live data from Hacker News

9999999999999999.0 – 9999999999999998.0

geocar.sdf1.org

31–40 of 274 posts

Re: 9999999999999999.0 – 9999999999999998.0

#31

DAE mind blown by imprecision in float arith? Edit: Down-Voters go ahead and explain the LIE that is computer accuracy in the face of the linked demonstration. Computers, can't trust em.

I didn't downvote you, but this isn't a problem with computers. It's a problem with the (mis)use of floats. Floats are not decimals. That's unfortunately a really, really common misconception, owing in part to poor education. Developers reach for floats to represent decimals without thinking about the precision ramifications. When you're working with decimals that don't need a lot of precision this doesn't generally…

FWIW, a fixed-precision floating-point decimal type would have the same problem. At some point the spacing between two consecutive floating-point values (ULP [1]) simply becomes more than one, no matter the radix.

[1] https://en.wikipedia.org/wiki/Unit_in_the_last_place

Re: 9999999999999999.0 – 9999999999999998.0

#32
The arithmetic is correct - the problem is that "9999999999999999.0" isn't representable exactly.

9999999999999998.0 in IEEE754 is 0x4341C37937E07FFF

"9999999999999999.0" in IEEE754 is 0x4341C37937E08000 - the significand is exactly one higher.

With an exponent of 53, the ULP is 2 - so parsing "9999999999999999.0" returns 1.0E16 because it's the next representable number.

    Using one of these workarounds requires a certain prescience of the
    data domain, so they were not generally considered for the table above.
Doing arithmetic reliably with fixed-precision arithmetic always requires understanding of the data domain. If you need arbitrary precision, you'll need to pay the overhead costs of arbitrary-precision: either by opting-in by using the right library, or by default in languages like Perl6 and Wolfram.

Re: 9999999999999999.0 – 9999999999999998.0

#33
post #20

$ php -v PHP 7.2.10 (cli) (built: Oct 9 2018 14:56:43) ( NTS ) $ php -r "echo 9999999999999999.0 - 9999999999999998.0;" 2 $ php -r "echo bcsub('9999999999999999.0', '9999999999999998.0', 1);" 1.0 bcmath - http://php.net/manual/en/function.bcsub.php

What happens with the bcmath extension enabled?

great point! edited to add. Decimal looks like a good option in php7, but a bit past a command line implementation: http://php-decimal.io/#introduction

Re: 9999999999999999.0 – 9999999999999998.0

#34

Are there any mainstream languages that consider a decimal number to be a primitive type? I feel like floating point numbers are far less meaningful in every day programs. Even 2d graphics would be easier with decimal numbers. Unless you're using numbers that scale from very small to very large, like 3d games or scientific calculations, you don't actually want to use floating point.

> Are there any mainstream languages that consider a decimal number to be a primitive type

Mathematica. But it's not particularely fast.

> Unless you're using numbers that scale from very small to very large, like 3d games or scientific calculations, you don't actually want to use floating point.

Unfortunately, we can sometimes only use floats in 3D graphics and floats aren't even good for semi-large to large 3D scenes. Unity is a particular bad offender. It's not even necessary for meshes but having double precision transformation matrices would make life so much easier. Could simply use double precision world and view matrices, then multiply them together and the large terms would cancel out in the resulting worldView matrix, which can then by cast back to single precision floats.

Re: 9999999999999999.0 – 9999999999999998.0

#35
Note in C you can get the correct result if you use long doubles, which normally go to 80 bits[1]:

printf("%Lf\n", 9999999999999999.0L - 9999999999999998.0L);

In my x86_64 computer it breaks when you add enough digits. At this point it started outputting 0.0 as the difference:

printf("%Lf\n", 99999999999999999999.0L - 99999999999999999998.0L);

With 63 bits for the fraction part you more or less get around 19 decimal digits of precision, and the expression above uses 20 significant digits.

[1] https://en.wikipedia.org/wiki/Extended_precision#x86_extende...

Re: 9999999999999999.0 – 9999999999999998.0

#37

What is the "right answer"? Is the article claiming that such languages don't respect IEEE-754, or that IEEE-754 is shit? If you want arbitrary precision, use an arbitrary precision datatype. If you use fixed precision, you'll need to know how those floats work. Pointless article, imho.

The point is to illustrate a simple fact that most of us know- but maybe some don't.

https://m.xkcd.com/1053/

Re: 9999999999999999.0 – 9999999999999998.0

#38

What is the "right answer"? Is the article claiming that such languages don't respect IEEE-754, or that IEEE-754 is shit? If you want arbitrary precision, use an arbitrary precision datatype. If you use fixed precision, you'll need to know how those floats work. Pointless article, imho.

There are several.

If you subtract two numbers close to each other with fixed precision you don’t know what the revealed digits are. (1000 +/- .5) - (999 +/- .5) = 1 +/- 1.

Thus 0, 1, and 2 are all within the correct range.

Re: 9999999999999999.0 – 9999999999999998.0

#39
I don't understand all the crap that IEEE 754 gets. I appreciate that it may be surprising that 0.1 + 0.2 != 0.3 at first, or that many people are not educated about floating point, but I don't understand the people who "understand" floating point and continue to criticize it for the 0.1 + 0.2 "problem."

The fact is that IEEE 754 is an exceptionally good way to approximate the reals in computers with a minimum number of problems or surprises. People who don't appreciate this should try to do math in fixed point to gain some insight into how little you have to think about doing math in floating point.

This isn't to say there aren't issues with IEEE 754 - of course there are. Catastrophic cancellation and friends are not fun, and there are some criticisms to be made with how FP exceptions are usually exposed, but these are pretty small problems considering the problem is to fit the reals into 64/32/16 bits and have fast math.

Re: 9999999999999999.0 – 9999999999999998.0

#40

DAE mind blown by imprecision in float arith? Edit: Down-Voters go ahead and explain the LIE that is computer accuracy in the face of the linked demonstration. Computers, can't trust em.

You're probably being downvoted for posting like you're on some other site, moreso than your sentiment that this is just a simple CS 101 thing that people ought to know. Thing is, a lot of people don't take CS courses, and have to learn this as they go along. More importantly, the naive cases all seem to work fine - it's only when you get to increasing precision / scales that you notice the cracks in the facade, and…

What is "properly" though? There's many real numbers that don't have finite representation. Arbitrary precision is all well and good, but as long as you're expressing things as binary-mantissa-times-2^x, you aren't going to be able to precisely represent 0.3. You could respond by saying that languages should only have rationals, not reals, but then you lose the ability to apply transcendental functions to your numbers, or to use irrational numbers like pi or e.

Performance is only part of the problem, and what it prevents is more-precise floats (or unums or decimal floats or whatever). The other part of the problem is that we want computers with a finite amount of memory to represent numbers that are mathematically impossible to fit in that memory, so we have to work with approximations. IEEE-754 is a really fast approximator that does a good job of covering the reals with integers at magnitudes that people tend to use, so it's longevity makes sense to me.

Post reply on HN