Need HELP: a funny and confusing thing happened

Hello, everyone! I need some help.

I am in Build a Cash Register of JavaScript Algorithms and Data Structures (Beta).

I want to calculate how many units of every denomination with cid.forEach(arr=>arr[1] / responsive denomination);

let cid = [
  ["PENNY", 1.01],
  ["NICKEL", 2.05],
  ["DIME", 3.1],
  ["QUARTER", 4.25],
  ["ONE", 90],
  ["FIVE", 55],
  ["TEN", 20],
  ["TWENTY", 60],
  ["ONE HUNDRED", 100]
];

responsive denomination part:

denomination = {
      penny: 0.01,
      nickel: 0.05,
      dime: 0.1,
      quarter: 0.25,
      dollar: 1,
      five: 5,
      ten: 10,
      twenty: 20,
      "one hundred": 100 
    }

but I got this:

{ penny: 101,
  nickel: 40.99999999999999,
  dime: 31,
  quarter: 17,
  one: NaN,
  five: 11,
  ten: 2,
  twenty: 3,
  'one hundred': 1 }

Why do I here get the nickel of

40.99999999999999

I thought the nickel should be 41, because it is the result of 2.05 / 0.5. Except nickel, all the rest are right numbers. Why ?

So can someone helps me ? Do I miss something ? What happened here ?

This is because how floating-point numbers are represented internally. Arithmetic operations on them can be inaccurate. This example shows that quite explicitly:

console.log(0.1 + 0.1 + 0.1 === 0.3)  // false
1 Like

thanks! But how should I calculate 2.05/0.05 for geting a right result ? I remenbered in previous lesson I learnt a way, like: parseInt((2.05/0.05).toFixed()). Can I use this ?

thanks! But how should I calculate 2.05/0.05 for geting a right result ? I remenbered in previous lesson I learnt a way, like: parseInt((2.05/0.05).toFixed()). Can I use this ?

I would use integer numbers of cents. Integers don’t have this issue

1 Like

Even tho money is often written as a floating point, it’s really an int.
eg, £1.25 is really 125 pennies.

You can work in integers then later convert back to decimal.
eg, 1.25 * 100 = 125 pennies
125 pennies % 100 = £1.25

1 Like

good idea, thanks! :smile:

1 Like

I have search and read some pages about this question.
I have found a website, floating-point-gui dot de , which foucuses on floating-point number. If you have same confuse, you can check it.

Eventually, in the “Build a Cash Register”, my way to deal with is:
Math.round( (2.05*100) / (0.05*100) ) / 100 . You can not just multiply them by 100 or 10000, because, in other cases, there are more than 2 bits or 4 bits after point in binary fraction. So I round them to an integer, then dividing the integer by 100. Why 100? Why not 1000 ? Because here my minimal money unit is 0.01, timesing 100 and dividing by 100 is enough precise.

Thanks, @Guided @sanity !

You don’t need to do decimal calculations at all if you convert to cents when your function starts, do all your arithmetic on integers of cents and then convert back to decimals at the end