Live data from Hacker News

0.30000000000000004

0.30000000000000004.com

301–310 of 422 posts

Re: 0.30000000000000004

#301
post #272

Earlier quoted context omitted.

when the fractions actually dont matter... its so painless just to just store everything in pennies rather than dollars (multiply everything by 100)

It’s not painless. E.g. dividing $100.00 by 12 month in integer cents requires 11 $8.33 and one $8.37 (or better 4x(2x8.33+8.34), depending on definition of ‘better’). You can forget this $0.04, but it will jump around in reports until you get rid of it – it requires someone’s attention anyway, no matter how small it is. Otoh, in unrounded floating point that will lead to a mismatch between (integer) payments and cal…

This struck home with me when one day a friend and I bought the same thing and he paid a penny more.

I realized something I didn't ever notice or appreciate in 20+ years: oh yeah, they can't just round off the penny in their favour every time. And the code that handles tracking when to charge someone an extra penny must be irritating to have developed and manage. All of a sudden you've got state.

Re: 0.30000000000000004

#302
post #130
post #91

Earlier quoted context omitted.

This is false. It's not correct to handle currency with floating point types.

They said floating point decimal types which probably means BCD.

Tbey mean radix-10 floating point, as compared to the radix-2 floating point you are thinking of. The packing of the decimal fractional digits in the significand of a radix-10 FP number need not be in BCD, it can use other encodings (e.g., DPD or something else).

0.3 is exactly representable in radix-10 floating point but not radix-2 FP (would be rounded to a maximum of 0.5 ulp error as seen in the title), for instance, just as 1/3 = 0.3333... is exactly representable in radix-3 floating point but neither radix-2 or radix-10 FP, etc.

Re: 0.30000000000000004

#303

Earlier quoted context omitted.

Fixed/floating is an interesting tradeoff for many real-time strategy games too where changes in game state are a synchronized simulation. Fixed point math in software can give more reliable and cross-platform math operations, but with a performance cost (eg: Homeworld: Deserts of Kharak). Using the CPU's floating-point hardware is faster, but you often have to ensure the correct CPU registers are set before doing ca…

I currently build deterministic multiplayer WebGL games in Unity, built via C#->IL2CPP->Emscripten->WASM. The server is the same code base running on Microsoft's .Net runtime. The chances of being able to run deterministic floating point calculations across this stack is basically zero (even leaving aside that the games are often run on ARM chips), and so we use this library when floats are absolutely necessary (but…

You use that library when you want fractional values right? That is, numbers with a binary point but not floats.

Re: 0.30000000000000004

#304
post #17

I remember in college when we learned about this and I had the thought, "Why don't we just store the numerator and denominator?", and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it's a thing people actually use: https://en.wikipedia.org/wiki/Rational_data_type

Some langs have that in their standard included batteries. (Shameless Common Lisp plug: http://clhs.lisp.se/Body/t_ration.htm )

Yes including C++, the language mentioned in the parent post (`std::ratio`)

Re: 0.30000000000000004

#305
post #109
post #17

I remember in college when we learned about this and I had the thought, "Why don't we just store the numerator and denominator?", and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it's a thing people actually use: https://en.wikipedia.org/wiki/Rational_data_type

Not all numbers are rational.

All floating point numbers are rational numbers.

Re: 0.30000000000000004

#306

Earlier quoted context omitted.

It's not correct, but it happens anyway, even in large ERP systems that really should know better but somehow don't.

It is correct! Using decimal types is the widely recommended way of solving this problem. That includes fixed and floating point types. The problem is using base-2 floating point types, since those are subject to the kinds of rounding errors in the OP. But decimal floating point types are not subject to these kinds of rounding errors. But they still can't precisely represent quantities like 1/3 or pi.

> Using decimal types is the widely recommended way of solving this problem.

No, it's not. The widely recommended way of solving this problem is to use fixed-point numbers. Or, if one's language/platform does not support fixed-point numbers, then the widely recommended way of solving this problem is to emulate fixed-point numbers with integers.

There is zero legitimate reason to use floating-point numbers in this context, regardless of whether those numbers are in base-2 or base-10 or base-pi or whatever. The absolute smallest unit of currency any (US) financial institution is ever likely to use is the mill (one tenth of a cent), and you can represent 9,223,372,036,854,775,807 of them in a 64-bit signed integer. That's more than $9 quadrillion, which is 121-ish times the current gross world product; if you're really at the point where you need to represent such massive amounts of money (and/or do arithmetic on them), then you can probably afford to design and fabricate your own 128-bit computer to do those calculations instead of even shoehorning it onto a 64-bit CPU, let alone resorting to floating-point.

Regardless of all that, my actual point (pun intended) is that there are plenty of big ERP systems (e.g. NetSuite) that use binary floating point numbers for monetary values, and that's phenomenally bad.

Re: 0.30000000000000004

#307
post #303

Earlier quoted context omitted.

I currently build deterministic multiplayer WebGL games in Unity, built via C#->IL2CPP->Emscripten->WASM. The server is the same code base running on Microsoft's .Net runtime. The chances of being able to run deterministic floating point calculations across this stack is basically zero (even leaving aside that the games are often run on ARM chips), and so we use this library when floats are absolutely necessary (but…

You use that library when you want fractional values right? That is, numbers with a binary point but not floats.

For the most part, I use longs (for instance a FixedVec is a (long,long,long) struct where 1 = 1/1000 of a meter).

However, complicated calculations or anything involving angles or other math functions quickly becomes more convenient when expressed as a Fix64, which is more or less a drop in replacement for float.

I would ideally use Fix64 everywhere, but given the torturous route the C# takes to be transformed into something that's executed on the client machines, my faith in the compiler's ability to generate good code for that is basically zero. I mentally treat long + long as a single instruction, but Fix64 + Fix64 as a function call.

Re: 0.30000000000000004

#308
post #272

Earlier quoted context omitted.

It’s not painless. E.g. dividing $100.00 by 12 month in integer cents requires 11 $8.33 and one $8.37 (or better 4x(2x8.33+8.34), depending on definition of ‘better’). You can forget this $0.04, but it will jump around in reports until you get rid of it – it requires someone’s attention anyway, no matter how small it is. Otoh, in unrounded floating point that will lead to a mismatch between (integer) payments and cal…

This struck home with me when one day a friend and I bought the same thing and he paid a penny more. I realized something I didn't ever notice or appreciate in 20+ years: oh yeah, they can't just round off the penny in their favour every time. And the code that handles tracking when to charge someone an extra penny must be irritating to have developed and manage. All of a sudden you've got state.

What kind of thing and store was it?

Re: 0.30000000000000004

#309
post #17

I remember in college when we learned about this and I had the thought, "Why don't we just store the numerator and denominator?", and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it's a thing people actually use: https://en.wikipedia.org/wiki/Rational_data_type

You either feel smart by wondering why people don't use rationals, or feel smart by wondering why people use rationals.

what do you mean by "rationals"? infinite precision? because finite precision rationals are not associative and much worse than floats in many senses.

Re: 0.30000000000000004

#310
post #20

The big issue here is what you're going to use your numbers for. If you're going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy. If you're handling money, or numbers representing some other real, important concern where accuracy matters, most likely any number you intend to show to the user as a number, f…

I'd agree for saner defaults, especially in web development. I can understand that if you want to have strictly one number type it may make sense to opt for floating point to eke out the performance when you do need it, but I'd rather see high-precision as the default (as most expect that you'd be able to write an accurate calculator app in JavaScript without much work) and opt-in to the benefit of floating point operations.
Post reply on HN