Live data from Hacker News

0.30000000000000004

0.30000000000000004.com

191–200 of 422 posts

Re: 0.30000000000000004

#191
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)…

> There's also BCD (binary coded decimal) that can solve some problems by avoiding the decimal-to-binary conversions if you're mainly dealing with decimal values. For instance 0.2 can't usually be represented in binary but of course it poses no problem in BCD.

BCD is/was super common in measurement equipment for internal calculations for this reason, and also because it is trivial to format for display (LED/LCD/VFDs) or text output (bus system, printer/plotter).

Re: 0.30000000000000004

#192
post #177

Earlier quoted context omitted.

Good catch! I'm thinking of fixed-point number types. Ruby's Rational was/is cool, but looks like an inherently difficult number-type to work with and keep sanity high. For currency, business side should decide the rules (* 100 or * 1000000), and where to funnel the pennies ;) Fixed-point has it's own sort of gotchas, ie. multiplication, power, division, sqrt, etc. So there are fancy techniques to work with the numbe…

When you start looking into all of this, it's interesting to see how many ways there are to represent numbers in a computer. It isn't actually obvious or trivial at all, there is no one "true" or "accurate" representation, and they all had to be invented by past computer scientists! If you're not a bank or similar but just dealing with currency to buy and sell things like for ecommerce, the default semantics of a fix…

Ask the COBOL guys and gals for the true answer ;)

There are accounting, balancing, laws, regulations and reconciliation issues where for the really serious stuff, you use whatever fit spec and requirements, not the other way around. Ruby's BigDecimal will be fine, if you implement the detailed specification about how to calculate each operation every step of the way, with designated precision at various steps, together with truncations along the way that may not make much sense to the developer (or anyone else, but are required to get correct numbers).

Point is, sometimes other parties need to be able to replicate the exact numbers, unrelated to any internal library or coding standards. Code using just plain integers could be easier to certify than a library dependency.

In such cases, you don't just round to make numbers prettier, but may even keep the truncated part of the equation. It's then nice to use simple stuff that are proven to work and not change over time.

Re: 0.30000000000000004

#193
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.

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.

Even decimal floating point is a bad idea (for dealing with money) since you still can't represent a subset of rational numbers without approximation and without introducing rounding error during some calculations. It's just a different subset than what binary floating point can represent without approximation.

Re: 0.30000000000000004

#195

Earlier quoted context omitted.

There is no "better floating point model" because floating point will always be floating point. Fixed point always has been and always will be an option if you don't like the exponential notation.

> Fixed point always has been and always will be an option Not really. It would be really cool if fixed point number storage were an option... but I'm not aware of any popular language that provides it as a built-in primitive along with int and float, just as easy to use and choose as floats themselves. Yes probably every language has libraries somewhere that let you do it where you have to learn a lot of function ca…

COBOL was created to serve the interests of the financial industry, therefore COBOL has fixed point as a first class data type.

Every programming language that has come since has been designed to be a general purpose programming language, therefore they don't include fixed point as a first class data type.

Therefore the financial industry continues to use COBOL.

Every time someone some tries to rewrite some crusty COBOL thing in the language de jure, they'll inevitably fuck up the rounding somewhere. The financial industry has complicated rounding rules. Or better yet, the reference implementation is buggy and the new version is right, but since the answers are different it's not accepted.

Re: 0.30000000000000004

#196

Earlier quoted context omitted.

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

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

This is just not true. If you add 1.5 + 4.25 with IEEE754, there is nothing inexact or rounded. That you cannot exactly represent 0.1 in base2 FP is a problem of base2, not FP.

You get inexact results with FP math for underflows, overflows, or if you don't have enough precision for the result (or an intermediate result). But the same is true for normal integer types.

Re: 0.30000000000000004

#197

Earlier quoted context omitted.

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

Amazon's EC2 hourly prices are rounded to mils ($0.011/hour). https://aws.amazon.com/emr/pricing/ Azure has some hourly prices with ten-thousandths of a cent ($0.0102/hour): https://azure.microsoft.com/en-ca/pricing/details/virtual-ma... Microsoft should use gas station 9/10 pricing conventions to just barely undercut Amazon's lowest price $0.011 with $0.0109. https://www.marketplace.org/2018/10/11/why-do-gas-prices-…

Tarsnap goes as low as counting attodollars. Yes, that's 10^-18 dollars, judging by the precision with which individual line items and total account funds are reported. Storage price is 250 picodollars per byte-month.

Re: 0.30000000000000004

#198

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, ...

I think you mean that storing money in floating point is always terrible for accounting. Not all of finance is accounting.

Imagine you work at a hedge fund, and you have a model that predicts the true value of some option. Assume the option is trading for $3.00. You do not really care if your model spits out $3.5 or $3.5000000001, you are going to buy either way. And your model probably involves a bunch of transcendental functions or maybe even non-deterministic machine learning, so it's not really meaningful to expect it to be “exact” to some decimal or even rational value.

Even more saliently, you probably don't care whether your model outputs 2.9999999 or 3.000000 or 3.000001, either, because in any of those cases the actual correct interpretation is “we’re just not sure whether to buy or not”.

I think a good first-order characterization of domains where floating point can safely be used is “when the difference between < and <= is not very meaningful” (in calculus terms: when “how meaningful is a difference of `x`” is a continuous function of `x`).

Re: 0.30000000000000004

#199

Earlier quoted context omitted.

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, ...

Storing money in floating point is fine. Just round to the nearest atomic unit when displaying. Sometimes this is a necessity when working with money in e.g. existing JSON APIs. You lose a few bits of range relative to fixed point storage but it's almost never a practical issue. Performing arithmetic operations against money in floating point is the dangerous part, as error can accumulate beyond an atomic unit.

There's very little point in storing money in floats if you're not going to do arithmetic in floats; about the only use case I can think of is JavaScript and JSON APIs.

Re: 0.30000000000000004

#200
post #174
post #91

Earlier quoted context omitted.

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

It's not correct, but in many cases it's plenty accurate

If you are dealing with other people’s money, the only accurate is accurate. Close enough should not be in any financial engineer’s mindset, imho.
Post reply on HN