Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ruby does have libraries for dealing with real numbers with an arbitrary precision.


And, in fact, Rails translates NUMERIC fields in the database to BigDecimal values in Ruby. (You still need to be careful, though that you don't inadvertently coerce a BigDecimal to a Float in the course of working with it.)


I haven't gotten very far with this issue in Ruby, however in PHP there is also a way to get around the lack of precision by treating numbers as strings and then using additional libraries to perform the necessary calculations. The ability to do this in a clear and concise manner and be absolutely certain that everything is adding up properly is not easy.

From my perspective, the fact that these calculations do not perform correctly right out of the box using dynamic languages is the problem, and adding additional libraries is not the solution.


The last project we did with money, we just treated all amounts as integers storing the number of cents. No accuracy problems w/ whole integers, so 1000 because $10.00. Easy to do math with, and keeps it's accuracy.

Might not work for hard-core financial work, since the number of decimals might be too deep for that to be efficient. (although there's nothing stopping you from saying the last 5 digits of every number is the decimal part).


A better thing to do is to not use raw integers to represent money at all, create an immutable money object, use integers to represent units and a currency string (cents/USD) inside the class. Use the money as the primitive it is, giving it the appropriate numerical operations added/subtracted/multiplied/allocated. Money is not an integer, or a decimal, or a double, or any other number, Money is Money and should be represented by an appropriate abstraction of its own.


As a bonus, this strategy also makes it (relatively) simple to handle multiple currencies. By using raw integers, you never have currency information attached so it's a lot tougher (and messier) to keep track of the currency.


> A better thing to do is to not use raw integers to represent money at all...Money is Money and should be represented by an appropriate abstraction of its own.

Good point. This makes me wonder though whether it is ever acceptable to use primitive math without some kind of units, except maybe in pure math. You are always counting something, be it dollars, or people, or widgets sold, or hard drive seeks.


I would depend on whether adding different units together was an error. 1 dollar + 1 euro should be an error. So raw numbers for pure counting is OK, but raw numbers for counting units of a specific measure are not OK, an abstraction should be introduced. If you just willy nilly add feet and meters you might end up missing your desired orbit and losing a billion dollar satellite.


I agree, and while the project we were on didn't have strong typing of money, what I described was the database storage of the numbers. We did very few calculations, and the system was explicitly USD, so going deep into "proper" handling of money was just unnecessary.

I really do like using the type system to keep track of units (type system either in the object oriented sense, or the haskell type system). This is similar to Joel's old article about using a naming scheme for dirty vs. sanitized strings for the web. It's all a type system, just his was in a language that didn't support language-level types.


php != dynamic languages


We're using his definition of dynamic languages which is PHP, Ruby, Perl, Python. Let's not fuss about definitions, let's be constructive here, hm?


Ruby and Python don't have the problem.


perl has bignums too.




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

Search: