Hacker News new | ask | show | jobs
by m00x 32 days ago
You can't do everything you need with an integer. There are values you might want to display or calculate with that are smaller than cents. In some places you'll need things like BigDecimal, which are immune to floating point errors in most cases.

It's also safe to return decimal values for displaying values.

2 comments

The integer `1` can mean whatever you want, it doesn't need to be a cent. Haskell's `Fixed` type is a good example of this:

https://hackage-content.haskell.org/package/base-4.22.0.0/do...

Its a wrapper around an `Integer` where you declare the scale in the type. So if you use `Fixed E2` as your type then `MkFixed 1` is 1 cent. If you did `Fixed E3` as your type then `MkFixed 1` is 0.1 cent. In both cases it is entirely an integer encoding.

But it's a good idea to keep those values distinct from actual money. You can't pay a fraction of a cent to anyone.
If you're calculating stock gains, taxes, etc. You'll want to do it on BigDecimal on line items, then sum it up. Cents could lose precision leading to a large difference on millions of line items.

If you're doing static payments or displaying a number, it doesn't matter if it's float amounts or integer cents since you're not doing any calculations anyway.

Stripe uses cents mostly because it's the most foolproof way that won't cause massive issues as a public API.

But the price of some unit of a commodity may well be expressed in smaller fractions to allow for small price changes.

You could argue that a price is not really an amount that anyone can actually pay and that's true. But it seems complex and error prone to store unit prices and amounts using different scaling factors.