Live data from Hacker News

0.30000000000000004

0.30000000000000004.com

161–170 of 422 posts

Re: 0.30000000000000004

#161
post #67
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

It's actually in use in many places, for things like handling currency and money, and for when you get funny corner cases involving rounding such numbers and pooling the change. Whenever I see someone handling currency in floats, something inside me wither and die a small death.

> It's actually in use in many places, for things like handling currency and money

Which specific places have you seen it used in?

Re: 0.30000000000000004

#162
post #138

Earlier quoted context omitted.

US currency can go to more than two decimal places... http://blogs.reuters.com/ben-walsh/2013/11/18/do-stocks-real... I guess it's time for someone to write an "Assumptions Programmers make about money" post.

Money is not as wierd as anyone might guess. I work on a financial application, and money is almost always just a BigDecimal with the scale set to 2 (and stored in a database as a bigint type or equivalent). When its not, its just a higher scale (for say, compound daily interest on small amounts for a significant period of time).

How do you store Bitcoin?

Re: 0.30000000000000004

#163

Earlier quoted context omitted.

It's not always terrible. I've seen doubles appropriately used in cases where performance was paramount, and floating point error was either not relevant or less important. That said, yeah, when working with money in situations where money matters, some sort of decimal or rational datatype should be the rule, not the exception.

Storing money in floating point is always terrible. If speed is an issue, store it in integer types representing the smallest unit in the currency, e.g. pennies. Unless you’re doing, what, massively parallel GPU algos on batches of independent amounts? But even then you could use the float as an int in that way... Honestly when is float ever actually good for money? Not for speed, not for correctness, ...

> If speed is an issue, store it in integer types representing the smallest unit in the currency, e.g. pennies

More typically, mills[1] (tenth of a cent).

[1]: https://en.m.wikipedia.org/wiki/Mill_(currency)

Re: 0.30000000000000004

#164
post #158

Earlier quoted context omitted.

You can still get reasonable enough approximations with more than two decimals if you do something like `int64 myWorkingMoneyVal = currentMoney * 100000`, do your work, then divide the final result by 100000. You still risk some potential truncation if your work involves division, but the larger your multiplier that you're working with, the larger divisor at the end, which will help minimize how much of an error this…

Google uses 1000000 as multiplier in their APIs. Edit: And they forbid equality comparisons for rationals. For some reason even >= is not allowed.

I didn't know that, but it doesn't surprise me (I suspected I wasn't the first person to come to the realization that there's no reason not to choose a giant number :) ).

Re: 0.30000000000000004

#165
post #79
post #67

Earlier quoted context omitted.

It's actually in use in many places, for things like handling currency and money, and for when you get funny corner cases involving rounding such numbers and pooling the change. Whenever I see someone handling currency in floats, something inside me wither and die a small death.

I haven't worked in fintech but I've read that money is often represented (at least in storage) as plain integers, since for example US currency only ever goes to two decimal places. But I guess once you start operating on it you run into potential truncation unless you use rationals.

In finance, US dollars are generally stored to four decimal places, because you need to deal with stuff like compounding interest or stock splits.

COBOL has a built in fixed point integer type, which makes defining a 4 digit decimal and doing math on it easy. (IBM designed it from the ground up to cater to people with a lot of money, who spend a lot of money, to work with lots of money, ie banks) Java has the BigDecimal type, which is a class in the class library, which means you need to import it. And because Java lacks operator overloading, doing calculations is tedious.

In the 90s, there was a huge push to replace COBOL with , and Java was the Rust of its day, so that's what everyone got behind. However, 4 digit COBOL decimals apparently round differently than 4 digit Java BigDecimals, so all the tests failed. And all the stuff like a\x+b had to be written like BigDecimal.add(BigDecimal.multiply(a,x),b) so development was taking forever.

Eventually they said "fuck it" and 20 years later we're still stuck with COBOL and everyone who remembers the original death march says "never again".

I have a feeling a lot of the problems came down to computer science people thinking money has two decimal digits but domain knowledge people knowing it has four. We programmers, as a group, make a lot of assumptions about other peoples' domains and we're wrong a lot*.

Re: 0.30000000000000004

#166
The runner up for length is FORTRAN with: 0.300000000000000000000000000000000039

And the length (but not value) winner is GO with: 0.299999999999999988897769753748434595763683319091796875

Re: 0.30000000000000004

#167

Earlier quoted context omitted.

It's not always terrible. I've seen doubles appropriately used in cases where performance was paramount, and floating point error was either not relevant or less important. That said, yeah, when working with money in situations where money matters, some sort of decimal or rational datatype should be the rule, not the exception.

Storing money in floating point is always terrible. If speed is an issue, store it in integer types representing the smallest unit in the currency, e.g. pennies. Unless you’re doing, what, massively parallel GPU algos on batches of independent amounts? But even then you could use the float as an int in that way... Honestly when is float ever actually good for money? Not for speed, not for correctness, ...

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.

Re: 0.30000000000000004

#168
post #148

Earlier quoted context omitted.

Falsehoods programmers believe about prices: https://gist.github.com/rgs/6509585

Interesting list, though I'm not sure what do they mean by n. 7

Apparently hyperinflation: https://www.wikiwand.com/en/Zimbabwean_dollar and https://currencyconvert.net/zimbabwe-dollar/dollar

Re: 0.30000000000000004

#169
post #128
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

An other compromise in to use fixed point which is effectively a rational with a fixed denominator. Extremely popular on machines which can handle integer arithmetics but not floating point (since you can trivially do fixed-point arithmetics using integer operations, you just need to be very careful when you handle overflows). If you look at the code of old school games (including classics like Doom if memory serves)…

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 calculations and those registers can be changed by other software such as a DirectX driver or the operating system (eg: Age of Empires II, Rise of Nations. etc).

Re: 0.30000000000000004

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

Decimal numbers are not conceptually any more or less exact than binary numbers. For example, you can't represent 1/3 exactly in decimal, just like you can't represent 1/5 exactly in binary. When handling money, we care about faithfully reproducing the human-centric quirks of decimal numbers , not "being more accurate". There's no reason in principle to regard a system that can't represent 1/3 as being fundamentally…

The real lesson is, no matter what base (radix) you use, floating point math is inexact.

The value of floating point is that it can represent extremely huge or extremely infinitesimal values.

If you're working with currency / money, floating point is the wrong thing to use. For the entire history of human civilization, currency has always been an integer type, possibly with a fixed decimal point. Money has always been integers for as long as commerce has existed, and long before computers.

If you're building games, or AI, or navigating to Pluto, then floating point is the tool to use.

Post reply on HN