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…
9999999999999999.0 – 9999999999999998.0
31–40 of 274 posts
Re: 9999999999999999.0 – 9999999999999998.0
#329999999999999998.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$ 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?
Re: 9999999999999999.0 – 9999999999999998.0
#34Are 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.
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
#35printf("%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
#36$ 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
Re: 9999999999999999.0 – 9999999999999998.0
#37What 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.
Re: 9999999999999999.0 – 9999999999999998.0
#38What 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.
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
#39The 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
#40DAE 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…
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.