In ruby do not use float for calculation since float is not good for precise calculation.
1irb(main):001:0> 200 * (7.0/100) 2=> 14.000000000000002
7 % of 200 should be 14. But float is returning 14.000000000000002 .
In order to ensure that calculation is right make sure that all the actors participating in calculation is of class BigDecimal . Here is how same operation can be performed using BigDecimal .
1irb(main):003:0> result = BigDecimal.new(200) * ( BigDecimal.new(7)/BigDecimal.new(100)) 2=> #<BigDecimal:7fa5eefa1720,'0.14E2',9(36)> 3irb(main):004:0> result.to_s 4=> "14.0"
As we can see BigDecimal brings much more accurate result.
Converting money to cents
In order to charge the credit card using Stripe we needed to have the amount to be charged in cents. One way to convert the value in cents would be
1amount = BigDecimal.new(200) * ( BigDecimal.new(7)/BigDecimal.new(100)) 2puts (amount * 100).to_i #=> 1400
Above method works but I like to delegate the functionality of making money out of a complex BigDecimal value to gem like money . In this project we are using activemerchant which depends on money gem . So we get money gem for free. You might have to add money gem to Gemfile if you want to use following technique.
money gem lets you get a money instance out of BigDecimal.
1amount = BigDecimal.new(200) * ( BigDecimal.new(7)/BigDecimal.new(100)) 2amount_in_money = amount.to_money 3puts amount_in_money.cents #=> 1400
Stay in BigDecimal or money mode for calculation
If you are doing any sort of calculation then all participating elements must be either BigDecimal or Money instance. It is best if all the elements are of the same type.