Live data from Hacker News

9999999999999999.0 – 9999999999999998.0

geocar.sdf1.org

261–270 of 274 posts

Re: 9999999999999999.0 – 9999999999999998.0

#261
post #247
post #212

Earlier quoted context omitted.

Yes, but the Julia REPL produces 2.0 as an answer and casting both these to BigInt doesn't work either.

Thus my second paragraph. You have to opt in to use other formats. Casting to bigint doesn't work because the problem occurs when converting the decimal constant in the source to floating point. You would have to convince the parser to parse the constant as something besides a float.

Agree - but it's a shame, fundamentally what ever the reason this is really, really egregious behaviour

Re: 9999999999999999.0 – 9999999999999998.0

#262

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.

C#

https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

Re: 9999999999999999.0 – 9999999999999998.0

#263

Earlier quoted context omitted.

My CS course at a community college went over the limitations of floats in detail, in the CS class.

How detailed, if I may ask?

I remember we learned how the representation worked bit-for-bit, and how it being stored in binary meant it couldn't perfectly represent everything in decimal. 1.01b meaning 12^0 + 02^-1 + 1*2^-2 for example.

Re: 9999999999999999.0 – 9999999999999998.0

#264

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

Yes, I have. I also have a math PhD, have written scads of scientific and numerical software, and have written articles on floating-point math. So now that we have enough of our personal accolades out of the way, let's focus on facts regarding calculations:

How did you use ints to compute compounded interest on loans? I asked that above, and you avoided it. I ask again.

For example, suppose you have a mortgage where you lent $100K at 5% annual, compounded 12 times a year, for 30 years, and you need basic values regarding this loan.

Often in such calculations you need to compute 100K*(1+0.05/12)^360. How do you do that with integers? Naively you need (1+(1/20)/12)^360, which as a reduced fraction each of the numerator and denominator have over 2800 binary digits. Do you really do this with integers?

Now put that in a mortgage trading or pricing system where it needs to do millions/billions of those per second.

Doing this as double gives enough precision to make the difference between computed and infinitely precise negligible (approx. 10^-17 error).

It's easy to make examples where doing incremental calculations, rounding to pennies and storing, results in long term error. In these cases I don't see how do to it with integers without massive overhead.

And this is a trivial, common example. Doing stuff like hedge fund stuff, or anything using numerical integration to make models for pricing, would be astounding hardly to do with integer only math.

What finance software did you write? A simple ledger works fine as integers. Anything more complex will hit performance and scaling issues soon after the basics.

Re: 9999999999999999.0 – 9999999999999998.0

#265

Actually Wolfram|Alpha does give 1, but Mathematica 11.3 gives 2.

Mathematica interprets the real numbers 9999999999999999.0 and 9999999999999998.0 as having machine precision. To work in arbitrary precision, you need a backtick after the number, followed by the number of significant digits.

In this case,

9999999999999999.0`17-9999999999999998.0`17 does indeed return 1.

https://reference.wolfram.com/language/ref/Precision.html

Re: 9999999999999999.0 – 9999999999999998.0

#266

Earlier quoted context omitted.

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

The x87 ISA does, yes, and they are supported for binary compatibility reasons. However the actual x87 registers are shadowed by the vector registers so you can only use one. Any modern vectorizing compiler uses the vector instructions for FPU arithmetic, even when scalar, with a max precision of 64-bit.

>The x87 ISA does, yes, and they are supported for binary compatibility reasons.

Well x86-64 is not binary compatible with x86 so that's not the reason. It is mostly for software relying on either the rounding quirks or the extended 80 bit precision I guess.

> However the actual x87 registers are shadowed by the vector registers so you can only use one

You are confusing with the legacy MMX registers which are deader than the x87 for stack. XMM registers do not shadow the for stack.

Re: 9999999999999999.0 – 9999999999999998.0

#267

Earlier quoted context omitted.

> 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…

Even with money I use integers. Instead of dollars (or local currency), I store values internally as pennies (or local equivalent 1/100 of main currency). Sometimes when working with interest I'll need to work with floats, and some databases I have values stored as DECIMAL(8,2) instead of INT, but for the most part I've saved quite a few headaches by keeping my values in INTs.

There are currencies that have the lowest value coin as 1/20 of main coin.

Re: 9999999999999999.0 – 9999999999999998.0

#268
post #97

Earlier quoted context omitted.

Not really. It's used for over 30 years successfully in all lisps. gmp is not really slow, and for limited precision (2k) there exist even faster libs.

gmp is not exact. It's just arbitrary-precision. There's a very large difference. Exact arithmetic handles numbers like pi with infinite precision. When you use gmp, you pre-select select a constant for pi with a precision known ahead of time. In the real world, 64 bits of pi is more than enough for almost every purpose, so whatever. It's fine. But there's a huge conceptual gap between that and exact arithmetic.

I never said that. For simple, non-symbolic languages gmp is still the best.

Lisp is of course better, optimizing expressions symbolically as far as possible, eg. to rationals, and using bignum and bigint's internally. As exact as possible. perl6 does it too, just 100x slower.

Re: 9999999999999999.0 – 9999999999999998.0

#269
post #201

Earlier quoted context omitted.

I believe IEEE754 floats have that subtraction/addition guarantee (as long as the hardware doesn't map subnormals to zero). The problem in this case is the input numbers are rounded when they are converted from text/decimal to a float, and so aren't exact.

> I believe IEEE754 floats have that subtraction/addition guarantee (as long as the hardware doesn't map subnormals to zero). They don't - all 11 bits of the exponent (for float64) are in use, so you can have something like 1e300, and then you can't e.g. add 1 to it and get a different number. >>> x = 1e100 >>> x 1e+100 >>> y = x + 1 >>> y 1e+100 >>> x - y 0.0

That's something else: x == y, so the difference must be 0. What you said above is

  if x != y, x - y != 0
which holds for all x and y, but is different to

  if dx != 0, x + dx != x
which fails for some (many!) x and dx.

Re: 9999999999999999.0 – 9999999999999998.0

#270
post #211
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…

To me the only downside of IEEE 754 is that most languages including C and C++ do not provide a sensible canonical comparison methods. This leads to surprised beginners and then a ton of home made solutions which are often not appropriate.

Would you really want a default comparison where a == b does not imply a - b == 0?
Post reply on HN