Live data from Hacker News

9999999999999999.0 – 9999999999999998.0

geocar.sdf1.org

181–190 of 274 posts

Re: 9999999999999999.0 – 9999999999999998.0

#181

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.

Bc?

Re: 9999999999999999.0 – 9999999999999998.0

#182

Earlier quoted context omitted.

You cannot do anything in finance with such reasoning. Take something simple, say a mortgage at 5% compounded 12 times a year. To compute payments using some fixed length representation or decimal is going to lead to more error than to use the usual floating point. This rabbit hole would continue for many applications. Floating point makes them all much easier to do well.

Have you worked on finance software? I have - we always used ints for everything, so we could avoid rounding suprises

I did a web project in the gambling space ~10 years back - we were legally required to perform all calculations as integers in ten thousandths of a cent (or millionths of a dollar).

We chose to _not_ do _any_ calculations client side in Javascript...

Re: 9999999999999999.0 – 9999999999999998.0

#183
post #71
post #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…

> considering the problem is to fit the reals into 64/32/16 bits and have fast math Floating-point numbers (and IEEE-754 in particular) are a good solution to this problem, but is it the right problem? I think the "minimum of surprises" part isn't true. Many programmers develop incorrect mental models when starting to program, and get no feedback to correct them until much later (when they get surprised). It is true…

Showing that the result of 9999999999999999.0 – 9999999999999998.0 is a number between 1.9999999999999998 and 2.0000000000000124 will not solve the problem. IEEE floating point doesn't keep track of loss of precision.

Re: 9999999999999999.0 – 9999999999999998.0

#184

Earlier quoted context omitted.

That hasn’t been the case for over a decade.

How do you mean? The x86-64 instruction set / abi specifies long doubles as 80-bits, and still supports them ...

Essentially there are two different sets of floating point instructions on x86 and x86-64: - the x87 instructions, which descend from the original 8087 coprocessor (and have 80-bit registers), and - the SSE instructions, which descend from the Pentium MMX feature set, are faster, support SIMD operations, and can be fully pipelined.

The x87 instructions are basically for legacy compatibility, or if you manually use long doubles on some platforms.

The idea behind extended precision registers was good in theory, but ultimately caused too much hassle in practice.

Re: 9999999999999999.0 – 9999999999999998.0

#185

So.. Can someone better versed in the ways of system level programming tell me why we still use IEEE 754 exponential notation? Iv'e seen article after article of how "horrible it is". So, are there default libs to use Binary Coded Decimal (BCD) or something like that?

Binary floating points are not for system level programming; they are for scientific programming, where the accuracy of the values is related to the magnitude of the values.

64 bit integers are actually good for a lot of things that floating point gets used for; coordinates already should never have been floating point (the accuracy of measurement is independent of the magnitude for coordinates), but you could represent the entire solar system in millimeters without overflowing 64 bit integers (compared to not even the entire earth in mm for 32 bit integers).

Also, it's popular to blame javascript for all today's problems, but the double-precision floating point is the only number type it has, which has some effect on its use.

Re: 9999999999999999.0 – 9999999999999998.0

#186
Well, one answer is to use IEEE 1788 interval arithmetic, which will at least give you IEEE 754 high and low bounds for a calculation, rather than one answer that's clearly wrong. Otherwise, some inaccuracy is the trade-off for fast floating point calculations.

Re: 9999999999999999.0 – 9999999999999998.0

#187
post #71

Earlier quoted context omitted.

> considering the problem is to fit the reals into 64/32/16 bits and have fast math Floating-point numbers (and IEEE-754 in particular) are a good solution to this problem, but is it the right problem? I think the "minimum of surprises" part isn't true. Many programmers develop incorrect mental models when starting to program, and get no feedback to correct them until much later (when they get surprised). It is true…

When I went to university in 1982, one of the lower level courses was called "Numerical Methods". It went over all of the issues related to precision, stability, as well as a host of common numerical integration and approximation methods. I'm just a sample size of one, but isn't this kind of class a requirement for CS majors?

It wasn't required at my school a decade or two later. Floating point representations were touched on somewhat in the intro to computer architecture class where we wrote assembly for a MIPS simulator. I got an extra dose because I switched my major to Math, where there was an entire course on Numerical Methods (though it wasn't required by either the Math or CS depts).

I'm a little amazed in retrospect that the Math department was where one had to go to get a class in the mechanical details of computing when as a subject it's usually considered (and often in practice is) notably up the ladder of abstraction. And this was a weird outlier as the single most practical upper division class offered by the Math department at the time...

Re: 9999999999999999.0 – 9999999999999998.0

#188

Do any of the languages mentioned give a compiler warning? To help educate?

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 digits, expecting exact representation?

The bigger gotcha here is catastrophic cancelation. This is the issue of an insignificant rounding error becoming much more significant due to subtracting of very nearly equal numbers. You can't generally detect this at compile time if you don't know all your numbers in advance (e.g. you're not working with only literals).

Re: 9999999999999999.0 – 9999999999999998.0

#189

Earlier quoted context omitted.

Yeah, the limitations of FP are well-known to anyone who does much numerical work. Floating point numbers are the optimal minimum message length method of representing reals with an improper Jeffery's prior distribution. A Jeffery's prior is a prior that is invariant under reparameterization, which is a mandatory property for approximating the reals. In this case, it is where Prob(log(|x|)) is proportional to a const…

There's no reason for every step of a computation to be confined to the same very small message length. And the necessary error analysis should be built into the language, preferably in the same "advanced users only, here be dragons" package as the imprecise types themselves.

[deleted]

Re: 9999999999999999.0 – 9999999999999998.0

#190

Earlier quoted context omitted.

How do you mean? The x86-64 instruction set / abi specifies long doubles as 80-bits, and still supports them ...

All the floating-point arithmetic that is natively supported these days is the 32- and 64-bit kind in SSE instruction sets and its extensions. The fact that something is "available" doesn't mean much in terms of actual support. As far as I know, long double means 128-bit floats in modern clang/gcc, and they are done in software.

Long doubles are typically 80-bit x87 "extended precision" doubles as far as I've seen. (Except on windows :-P ). It's part of the reason why LLVM has the 80 bit float type.

https://en.cppreference.com/w/cpp/language/types

https://software.intel.com/en-us/articles/size-of-long-integ...

They are definitely still supported in modern Intel processors. That said, there can be some confusion because they end up being padded to 16 bytes for alignment reasons, so take 128 bits of memory, but they are still only 10 byte types.

They are a distinct type from the "quad" precision float128 type, which is software emulated as you mentioned.

All that being said, you are right that most of the time float math ends up in SSE style instructions, but as soon as you add long doubles to the mix, the compiler will emit x87 style float instructions to gain the extra precision.

Example: https://godbolt.org/z/PMZVdb

Post reply on HN