Representing money


(Andy Jones) #1

Re: "Behaviour of round changed?".
Pardon my curiosity -- what do you use to represent money in your code? It seems to me that the choices are between:

1) BigDecimal

2) Rational

3) A custom class
To my way of thinking, if you are multi-currency, you almost certainly want #3; but otherwise it's down to personal preference? I plumped for BigDecimal, but I wonder if it would have been easier on me if I had gone for Rational instead?

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>

Please note that we have updated our privacy policy in line with new data protection regulations. Please refer to our website to view the ways in which we handle your data.


(Xavier Noria) #2

It depends on how do you use the numbers. For example, if you need exact
division, then rationals are the safest bet.

Big decimals don't have exact division because they can only represent
numbers whose decimal representation is finite.


(Walter Lee Davis) #3

I use integer "cents" and the Money gem to deal with the localization details. This works perfectly in a multi-currency Web store. I only ever store cents, and convert all presentations on the fly into whatever passes for dollars and cents with a decorator method wrapped around Money:

...
Money.new(price_in_cents, currency).format
...

Walter

···

On Jan 8, 2019, at 10:25 AM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

Re: “Behaviour of round changed?”.

Pardon my curiosity -- what do you use to represent money in your code? It seems to me that the choices are between:

1) BigDecimal

2) Rational

3) A custom class

To my way of thinking, if you are multi-currency, you almost certainly want #3; but otherwise it’s down to personal preference? I plumped for BigDecimal, but I wonder if it would have been easier on me if I had gone for Rational instead?


(Greg Navis) #4

Use integers and represent $1.23 as 123. If you need to specify the
currency then you may need a custom class (or a gem) but that problem is
orthogonal to representing the numerical part. Decimals won't save you
because if you send "1.333" to an third-party system then it can either
raise an error or truncate to "1.33".

You need to keep in mind that money arithmetic is different from normal
arithmetic. Say you want to divide $10 into 3 installments. If you do
rationals then 10 / 3 is 3 x 3.(3) which likely will get truncated to 3.33
and you'll end up with 9.99 in total. Same for increasing/decreasing
amounts by a given percentage. For example, if you want to give a 10%
discount off $9.99 then the exact result is $8.991.

Best regards
Greg Navis


(Otavio Valadares) #5

We use integers "cents" with money <https://github.com/RubyMoney/money> on
a multi-currency marketplace and works as expected. I'm grateful.

···

On Tue, Jan 8, 2019 at 1:37 PM Walter Lee Davis <waltd@wdstudio.com> wrote:

> On Jan 8, 2019, at 10:25 AM, Andy Jones <Andy.Jones@jameshall.co.uk> > wrote:
>
> Re: “Behaviour of round changed?”.
>
> Pardon my curiosity -- what do you use to represent money in your code?
It seems to me that the choices are between:
>
> 1) BigDecimal
>
> 2) Rational
>
> 3) A custom class
>
> To my way of thinking, if you are multi-currency, you almost certainly
want #3; but otherwise it’s down to personal preference? I plumped for
BigDecimal, but I wonder if it would have been easier on me if I had gone
for Rational instead?
>
>

I use integer "cents" and the Money gem to deal with the localization
details. This works perfectly in a multi-currency Web store. I only ever
store cents, and convert all presentations on the fly into whatever passes
for dollars and cents with a decorator method wrapped around Money:

...
Money.new(price_in_cents, currency).format
...

Walter

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
Otavio Valadares
@ValadaresOtavio


https://www.linkedin.com/in/otavio-henrique/
https://otaviovaladares.com/ <http://otaviovaladares.com>