Skip to content

Instantly share code, notes, and snippets.

@alexitaylor
Last active April 27, 2017 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexitaylor/1550400a047cf8ae614499eedbc12861 to your computer and use it in GitHub Desktop.
Save alexitaylor/1550400a047cf8ae614499eedbc12861 to your computer and use it in GitHub Desktop.
/* Prompt: tackling floating-point imprecision with the CashAmount class
In programming languages such as JavaScript, 0.1 + 0.2 does not equal 0.3. This is true in Ruby, Python, etc. The imprecision is inherent in floating-point arithmetic, it isn't because JavaScript itself is wonky.
These tiny errors can add up and cause actual wrong answers over time if you're not careful. They also make it harder to unit-test your work, since you have to compare within ranges rather than comparing to exact expected values.
To deal with this specifically within a monetary context, let's make a class called CashAmount that accepts double values (e.g., 14.72) and will never suffer from the aforementioned precision problems. A CashAmount represents a collection of bills and coins, such as you might find in your wallet, purse, or a cash register.
Note: you can do this by converting to pennies for all denominations so you are always working with integers, then converting back to a two-decimal float as needed. */
const CashAmount = function(value) {
this.value = value;
};
CashAmount.prototype.totalInPennies = function() {
return parseInt(parseFloat(this.value).toFixed(2).toString().replace('.', ''))
}
CashAmount.prototype.addDoubleAmount = function(addTo) {
this.value += addTo;
}
CashAmount.prototype.toDouble = function() {
return this.value.toFixed(2)
}
CashAmount.prototype.toDoubleString = function() {
return this.value.toString()
}
CashAmount.prototype.quantityOfEachDenomination = function() {
var quantity = {
'hundreds': 0,
'fifties': 0,
'twenties': 0,
'tens': 0,
'fives': 0,
'ones': 0,
'quarters': 0,
'dimes': 0,
'nickels': 0,
'pennies': 0
}
var amtArray = [100, 50, 20, 10, 5, 2, 1, .25, .10, .05, .01];
for (var i = 0; i <= amtArray.length; i++) {
console.log(parseInt(value / amtArray[i]))
//console.log(value % amtArray[i]);
}
}
const cash = new CashAmount(10.50);
console.log(cash.totalInPennies()); // -> 1050
cash.addDoubleAmount(29.33);
console.log(cash.totalInPennies()); // -> 3983
console.log(cash.toDouble()); // -> 39.83)
console.log(cash.toDoubleString()); // -> '39.83')
const moreCash = new CashAmount(0.10);
moreCash.addDoubleAmount(0.20);
console.log(0.10 + 0.20 === 0.30); // -> false
console.log(moreCash.totalInPennies() === 30); // -> true
const moarCash = new CashAmount(967.93);
moarCash.quantityOfEachDenomination() // ->
var expected = {
'hundreds': 9,
'fifties': 1,
'twenties': 0,
'tens': 1,
'fives': 1,
'ones': 2,
'quarters': 3,
'dimes': 1,
'nickels': 1,
'pennies': 3
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment