Hacker News new | past | comments | ask | show | jobs | submit login

for any APIs related to money, should the currency be in strings as opposed to in floats? This will prevent accidental float arithmetic in the code. I always find it tricky to work with currency in javascript.



From their docs [1] it looks like they do everything using integers: the amounts are integers in the "minor unit" of currency, for example cents if the currency is dollars. So 1000 means $10.00. In languages like JavaScript where everything is a float64, you can still accurately represent integers up to 2^53, which would be $90 trillion.

[1] https://increase.com/documentation/api#transactions


This isn't sufficient to represent prices which often include fractional amounts of cents in non-retail scenarios. Think of AWS server prices per hour.


Funny, because that's exactly what Stripe does (https://docs.stripe.com/billing/subscriptions/usage-based/pr...)


But those are decimal values, not integers. I didn't mean that using cents as a unit was insufficient, I meant that using integers was.


Yes, never use floats for currency. I typically use integers and for USD for example, measure in "cents" rather than dollar. I try to avoid the fallacy of appeal to authority, but this is what Stripe does. You can also use the Decimal type in javascript and convert to/from strings to cross API boundaries.


Ideally integers, but at a large multiplier.

Google's money proto [1] has units and nanos. Any competent ad-tech system will use something similar: integer number of micro-dollars, nano-dollars, etc. You want a fair amount of precision, so just tracking whole cents isn't enough, but you want that precision to be (linearly) equally distributed across the value space so that you can make intuitive guarantees about how much error can accumulate.

[1] https://github.com/googleapis/googleapis/blob/master/google/...


I will be the contrarian: JSON numbers are not floating point values, they are strings of characters matching the format "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?". You can choose to parse them however you want, and parsing libraries should provide a mechanism to decode to an arbitrary-precision value.


Good point. it's not a problem with JSON. It's just that most of the JSON libraries by default parse numbers into floats.


By way of example: when I worked on payment code in Java, we accepted numeric JSON values in request payloads but they were deserialized into "BigDecimal" fields in our payload classes, not "float" or "double".


Regardless of what the libraries should be doing, there is the reality of what they are doing.


Luckily, there are not many broken JSON parsers out there, as this is a well-known issue. Just about the only parser that remains broken is Javascript's JSON.parse(), because it doesn't allow for any options to control the parser, which is why we keep having this discussion.


Yes, but say in javascript if you do a JSON.parse(), it will give you a double float right?


Yes, because JSON.parse() treats the input as if it were a JS object literal; that is, JSON.parse(JSON.stringify(someObject)) will be idempotent. Usually parser libraries let you construct a parser with options, so you'd make a "let json = JSON({parseNumbersAsBignums: true})" and use that everywhere, but JS doesn't have that built in.


I've always seen currencies multiplied by 100 to remove the need for floating point.


If you use a higher constant, 10000 or 1000000 or something, you give yourself a good amount of more fleixibility.


Some currencies use more than 2 decimal places. For instance, the currencies of Algeria, Bahrain, Iraq, Jordan, Kuwait, Libya, and Tunisia are subdivided into 3 decimals.


That's not quite a sufficient rule. Eg, 1 Bahraini Dinar is 1_000 Bahraini Fils.


Yeah, this seems like a common pattern. Not sure about currency with arbitrary place values though (like Bitcoin)


I'm not sure what you mean by "arbitrary place values" with Bitcoin; if you are implying it's infinitely divisible, it isn't. You'd do the same trick with Bitcoin: represent it as an integer¹. The value 1 is 1 sat, or 0.00000001 BTC.

¹(where you need to; otherwise, I'd use some fixed point type if my language supports it)


neither. Use rational or some other better type.


You should never use floats for dinero. And it has nothing to do with JS, though i find it funny that you mention JS.


Don't use floats if you're trying to represent an exact value, i.e. someones bank account. But in financial modelling you're generally dealing in probabilistic "expected values", it's common and fine to use floats.

Having said that, half the world seems to run on Excel spreadsheets, which are full of money values, and Excel is basically all floats (with some funky precision logic to make it deterministic - would be curious to know more).

https://stackoverflow.com/questions/2815407/can-someone-conf...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: