Live data from Hacker News

0.30000000000000004

0.30000000000000004.com

381–390 of 422 posts

Re: 0.30000000000000004

#381

Earlier quoted context omitted.

You can get a larger error than that using one operation. fn main() { let x: f64 = 9007199254740992.0; assert_eq!(x + 1.0, x); }

You are absolutely right. When adding numbers with large magnitudes differences (around 10^17 I think) it might exceed the format precision. I should have taken that in account when defining the error boundaries. In dollars, you start having issues with cents when working with a tens of trillions. For the vast majority of people this won't be an issue.

[deleted]

Re: 0.30000000000000004

#382

Earlier quoted context omitted.

And that roughly captures the spot where I was seeing doubles used. Yes, they could have used fixed point. I am guessing that what happened is that someone who had thought way more deeply about this than I ever needed to (I worked on the accounting side, where, yep, we always used decimals) either determined that, where the modeling was concerned, floating point errors were not worth worrying about, or estimated that…

To see 0.1 error using _double_ you have to do at least 2*10^17 operations (assuming the worst case scenario and no subnormals). If you are working with such huge numbers, 0.1 cents is probably a cost you are willing to pay to avoid expending thousands in a software solution. The saving with power saving using a floating point is likely greater than power your computers will have to expend to get a precise solution.

I can give you 1.0 error. Take a handful of numbers that add up to 1.5, sum them, and then round that result to the nearest unit.

I'm too lazy to figure out a specific example, but sets of numbers where doubles round up and decimals round down (or vice versa) aren't terribly uncommon.

Re: 0.30000000000000004

#383
I wish high level languages (specifically python) would default to using decimal, and only use a float when cast specifically. From what I understand that would make things slower, but as a higher level language you're already making the trade of running things slower to be easier to understand.

That said, it's one of my favorite trivia gotchas.

Re: 0.30000000000000004

#384
post #380

Earlier quoted context omitted.

In a language like Java, all these factors are specified and fully deterministic.

False. Floating-point arithmetic in Java is generally nondeterministic. You will notice that the strictfp keyword exists and is off by default.

It's not false - strictfp mandates deterministic FP. If you use that your program will always run all floating point calculations in exactly the same way, full stop.

Secondly, on mainstream implementations, strictfp is already documented the same as default! They're planning to remove it anyway as it's a no-op in almost all cases.

See JEP 306.

Re: 0.30000000000000004

#386

Earlier quoted context omitted.

My day job is high performance financial model implementation. Floats storing dollar amounts are the norm for predictions. Operating on values that are linear combinations of integer fractions multiplied by irrational constants (such as Euler’s number) is perfectly possible, but it’s much more performant to be aware of floating point epsilon when writing modeling code.

Financial models are predictive, they don't have to be accurate to a penny, right? Unlike processing actual money people own. (I do some work with predictive simulations about money, but outside finance, and there we care that the result has accurate order of magnitude. Floats were used extensively in the project; I actually upgraded them to doubles for the sake of handling larger order of magnitude spans.)

That’s right. The trading desk also uses floats for analysis and regulatory reporting. Actual account balances come through an API that gives us floats, but rumor has it that it’s backed by Hollerith a punch card library maintained by cybernetic undead, encoded in 1215-EBCDIC-BLACKTONGUE.

Re: 0.30000000000000004

#387
post #243

Earlier quoted context omitted.

Currency in banking is handled with bigints. Not rationals, just bigints of the smallest unit (i.e., 1 cent). This forces you to order operations so that divisions are done last or not at all.

The bigint you describe is just a poor man's rational, given that no computer architecture or mainstream language support them natively.

There is a slight difference where it forces decision-making about rounding at every step. Most importantly, it makes errors that print money (or burn money) impossible states. I'm aware of BigRational libraries or more clever currency abstractions, but this is the least magical way of doing it, kind of like representing datetimes as 64-bit UNIX epochs.

Re: 0.30000000000000004

#388
post #246

Earlier quoted context omitted.

Bitcoin uses fixed-width unsigned integers. The smallest unit is 10^-8 of 1 Bitcoin, which is represented as just 1.

I like this approach. Is it compatible with the parent comment?

Yes, the parent approach is the same thing but with a decimal point added for convenience. The main thing is that the scale is fixed; it is effectively an integer count of 1s of the least significant index. It is impossible to truncate values or round upward and create money that didn't exist. This makes it perfect for representing actual money.

Re: 0.30000000000000004

#389
post #350

Earlier quoted context omitted.

But it is correct. > It's easy to write a program that sums up 0.01 until the result is not equal to n * 0.01. It's not easy to do that if you use a floating point decimal type, like I recommended . For instance, using C#'s decimal, that will take you somewhere in the neighborhood of 10 to the 26 iterations. With a binary floating point number, it's less than 10.

That is simply not true. The C# decimal type doesn't accumulate errors when adding , unless you exceed its ~28 digits of precision. E.g. see here: https://rextester.com/RMHNNF58645

> unless you exceed its ~28 digits of precision

Precisely. That's why I specified ~ 10^26 addition operations.

Re: 0.30000000000000004

#390
post #315

Earlier quoted context omitted.

Hear, hear! It would be great if javascript had any integral type that we could build decimals, rationals, arbitrarily-large integers and so on off. It’s technically doable with doubles if you really know what you’re doing, but it would be so much easier with an integral type.

ES does have an arbitrarily large integer type, BigInt. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Though the lack of support in IE, current Edge, and Safari, blocks that from client-side use for many.

There are several BigInt libraries out there that you could use, though obviously this is not as convenient and even if they wrap BigInt when available will be less efficient.

Post reply on HN