Thanks everyone. The money gem looks okay, given that the precision can be set per currency, but I'm probably going to stick with BigDecimal.
I want AUD to at least 2 decimal places and units of an equity to at least 8 decimal places. My current preference is to use one kind of number that works for everything. Using an integer is difficult because I'd need to also store what kind of unit it is. I think I'll wrap BigDecimal, to ensure I'm always using #div and #mult instead of / and *, and always with the correct precision. I could monkey patch BigDecimal to warn if it's been instantiated unexpectedly, but that's probably overkill. I'll store them in PostgreSQL as NUMERIC, which allows for a precision (total significant digits) and scale (decimal places) and will need it to be a little bigger to handle both my cases with one type. PostgreSQL does "round to nearest, round half away from zero". BigDecimal also allows "round to nearest, round half to even", which is less biased, but I'll stick with "round to nearest, round half away from zero" there too, because I think that will be okay and I want to use one kind of rounding everywhere. So I'll have reasonable and reliable precision and rounding, then the only other thing is to make sure that calculations are done in a way that doesn't amplify the rounding that does take place. Data is passed around in JSON, and to make that work reasonably I'll use strings rather than ints or floats. I think that the type of precision provided by https://github.com/jgoizueta/flt might actually be better, but I'm not inclined to use it for now because it's not as fast (currently in pure Ruby) and more importantly, I'm using the Sequel gem to talk to the DB, and Sequel knows how to handle BigDecimal (but not Flt::DecNum). Cheers, Chris On Mon, Feb 24, 2014 at 11:10 PM, Simon Russell <si...@bellyphant.com>wrote: > This is possibly getting quite off track, but the money gem's lack of > understanding of the details of different currencies is why I've always > ended up rolling my own. Unfortunately I never actually get around to > releasing it as a gem... > > I also haven't looked at it in a while, but from what I remember the money > gem's not afraid of the odd silent floating point calculation as well; > which more-or-less rules it out for me. > > However, there's nothing wrong with rounding/truncating between operations > assuming it has the precision you need. It's quite possibly more correct. > > The trick is to know when the rounding is occurring and minimise it. Or > apply the appropriate legislated rules, if there are any. If you're relying > on excess precision in the middle of an algorithm, you're still rounding, > just not as obviously. > > Anyway, let's hope Chris's original question gets answered; there are at > least a few directions to go in this thread. > On 24 Feb 2014 22:52, "Steven Ringo" <goo...@stevenringo.com> wrote: > >> >> The money gem is definitely not what you are after as it rounds way too >> much. It may compute with integer computation (I havnt looked) however it >> stores 2 decimal places and seems to round between each computation. >> >> >> Are you sure? You can set currency exponent ( >> https://github.com/RubyMoney/money#currency-exponent) to as many decimal >> places as you like. >> >> This unfortunately makes it unusable for any money application where >> division or multiplication is needed. It is possibly useful to help >> translate between currencies.. however even then a higher precision would >> probably be in order >> >> If that doesn't sway you try (19.957).to_money on the console :) >> >> >> No definition of "money" here is provided. What currency is it? How has >> it been defined? Sure if its USD to 2 decimal places then it will round. >> But nothing stops you from defining a currency as USD to say 6 decimal >> places. >> >> Of course the BigDecimal gem may be exactly what you need. >> >> Steve >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby or Rails Oceania" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to rails-oceania+unsubscr...@googlegroups.com. >> To post to this group, send email to rails-oceania@googlegroups.com. >> Visit this group at http://groups.google.com/group/rails-oceania. >> For more options, visit https://groups.google.com/groups/opt_out. >> > -- > You received this message because you are subscribed to the Google Groups > "Ruby or Rails Oceania" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rails-oceania+unsubscr...@googlegroups.com. > To post to this group, send email to rails-oceania@googlegroups.com. > Visit this group at http://groups.google.com/group/rails-oceania. > For more options, visit https://groups.google.com/groups/opt_out. > -- You received this message because you are subscribed to the Google Groups "Ruby or Rails Oceania" group. To unsubscribe from this group and stop receiving emails from it, send an email to rails-oceania+unsubscr...@googlegroups.com. To post to this group, send email to rails-oceania@googlegroups.com. Visit this group at http://groups.google.com/group/rails-oceania. For more options, visit https://groups.google.com/groups/opt_out.