Live data from Hacker News

9999999999999999.0 – 9999999999999998.0

geocar.sdf1.org

221–230 of 274 posts

Re: 9999999999999999.0 – 9999999999999998.0

#221
post #200

> Several of the results surprised me. Did they surprise you? Well, the perl6 result surprised me, since that means it's using something more precise than double precision floating point :)

It surprised me too, since it's not what I got. $ perl6 --version This is Rakudo version 2018.03 built on MoarVM version 2018.03 implementing Perl 6.c. $ perl6 -e 'print 9999999999999999.0-9999999999999998.0;print "\n";' 2 $ (Incidentally, I would have used "say" rather than "print" with an explicit newline.)

  › perl6 -e '.say for $*PERL.compiler, 9999999999999999.0-9999999999999998.0'
  rakudo (2018.11)
  1

Re: 9999999999999999.0 – 9999999999999998.0

#222

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.

> Pointless article, imho.

I'm sorry you thought so. It pops up pretty often and always seems to spark a lot of conversation, so I think most programmers that give it any thought can find it a very interesting area of study.

There's an incredible amount of creep: We have what starts with nice notation (like x-y) and have to trade a (massively increased) load in either our minds or in the heat our computer generates. I don't think that's right, and I think the language we use can help us do better.

> What is the "right answer"?

What do you think it is?

Everyone wants the punchline, but this isn't a riddle, and if this problem had a simple answer I suspect everyone would do it. Languages are trying different things here: Keeping access to that specialised subtraction hardware is valuable, but our brains are expensive too. We see source-code-characters, lexicographically similar but with wildly differing internals. We want the simplest possible notation and we want access to the fastest possible results. It doesn't seem like we can have it all, does it?

Re: 9999999999999999.0 – 9999999999999998.0

#223

The author says, "That Go uses arbitrary-precision for constant expressions seems dangerous to me." Why? My thoughts: 1) more inefficient programs because encountering an arbitrary-precision expression requires arbitrarily large memory and computation, 2) more complicated language implementation.

> Why?

Hint 1: Can you imagine ever moving a magic number from an expression into a constant?

Re: 9999999999999999.0 – 9999999999999998.0

#224
How do Perl, Wolfram ans Soup get the "right" (ahaha...) answer ? (I'm not familiar with these langages)

Of course for others it should "fixable" where needed:

  ~ python3
  Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
  [GCC 8.2.0] on linux
  Type "help", "copyright", "credits" or "license" for more information.
  >>> from decimal import Decimal
  >>> Decimal('9999999999999999.0') - Decimal('9999999999999998.0')
  Decimal('1.0')

Re: 9999999999999999.0 – 9999999999999998.0

#226

Earlier quoted context omitted.

Outside of the academic world decimals are almost always a better solution if performance isn't critical. Most logic is multiplicative. For example, apply a 30% tax on a dollar quantity and display both subtotal and grand total. With floats, there are inequalities. With decimal there usually aren't unless you're dividing, but we already have to deal with divide errors in base ten, and it is much more likely to need t…

> Outside of the academic world decimals are almost always a better solution Is “academic world” now a shorthand for “all numerical computing”? Decimals basically never make sense, except possibly in some calculations related to money. Those make up a minuscule part of modern computer use. Maybe decimals are also better for homework assignments for schoolchildren? The type of applications where decimals are useful ar…

No need for snark. You might be correct that, by “computational volume”, handling currency values might be considered a niche; but even something like World of Warcraft has to handle money at some point.

Re: 9999999999999999.0 – 9999999999999998.0

#227
post #215

With python, I get 2 even when using Decimals. Python 2.7.3 (default, Oct 26 2016, 21:01:49) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from decimal import * >>> getcontext().prec 28 >>> a=Decimal(9999999999999999.0) >>> b=Decimal(9999999999999998.0) >>> a-b Decimal('2') That is unexpected.

This is because you create a python float (64-bit) before passing this float to the Decimal class.

  >>> a = 9999999999999999.0
  >>> a
  1e+16

Re: 9999999999999999.0 – 9999999999999998.0

#228

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.

Take a piece of pen and paper and subtract the two numbers. Whatever number you get for the difference is "the right answer."

Ok, I'll try with pi and e. I'll be right back.

Re: 9999999999999999.0 – 9999999999999998.0

#229

Earlier quoted context omitted.

IMHO it's unfeasible, because the exact same situation as with 9999999999999999.0 (a literal that's impossible to represent accurately as double and will get rounded to something else) applies also to very common cases such as 0.1 (which can't have an exact binary representation at all) - adding a compiler warning for that will mean that the warning will trigger for pretty much every floating point literal.

I don't think that's quite true. For 0.1,the algorithm for printing back the number will still result in 0.1, but the same is not true for 9999999999999999.0, which comes back 1e16. So compilers could easily warn for this specific situation, where what I'd call the round trip value of the literal is broken. But I don't think such a warning would be all that helpful. How often do we use literals with 16 significant di…

You can do abstract interpretion and calculate rounding precision at each line. The problem is that as soon as you have loops, you'll pretty much get that warning everywhere. Being sure that there is no cancellation is even harder, but possible in some cases. I'm sure there are better approaches, there's tons of research papers in that area.

Re: 9999999999999999.0 – 9999999999999998.0

#230
The linked post is a bit poorly expressed, but I think there is a good point there: fixed-size binary floating-point numbers are a compromise, and they are a poor compromise for some applications, and difficult to use reliably without knowing about numerical analysis. (For example, suppose you have an array of floating-point numbers and you want to add them up, getting the closest representable approximation to the true sum. This is a very simple problem and ought to have a very simple solution, but with floating-point numbers it does not [1].)

Perhaps it is time for the developers of new programming languages to consider using a different approach to representing approximations to real numbers, for example something like the General Decimal Arithmetic Specification [2], and to relegate fixed-size binary floating-point numbers to a library for use by experts.

There is an analogy with integers: historically, languages like C provided fixed-size binary integers with wrap-around or undefined behaviour on overflow, but with experience we recognise that these are a poor compromise, responsible for many bugs, and suitable only for careful use by experts. Modern languages with arbitrary-precision integers are much easier to write reliable programs in.

[1] https://en.wikipedia.org/wiki/Kahan_summation_algorithm [2] http://speleotrove.com/decimal/decarith.html

Post reply on HN