0

Hello I am trying to build a function in javascript to check if a decimal number is multiple of another decimal number:

var num1 = 0.0002;
var num2 = 0.0001;

var remainder = (num1 % num2);
console.log(remainder);

if (remainder === 0) {
  console.log('️ num1 multiple of num2'); //IF remainder is zero, so num1 is multiple of num2
} else {
  console.log('⛔️ num1 NOT multiple of num2');
}

But when the num1 is 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, etc is not working. In this cases the result is 0.00009999999999999996

num1 = 0.0008 is working

Why this happens and how to fix?

Jhonny I.
  • 13
  • 4
  • "In JavaScript all numbers are IEEE 754 floating point numbers. Due to the binary nature of their encoding, some decimal numbers cannot be represented with perfect accuracy. This is analagous to how the fraction 1/3 cannot be accurately represented with a decimal number with a finite number of digits. Once you hit the limit of your storage you'll need to round the last digit up or down." http://adripofjavascript.com/blog/drips/avoiding-problems-with-decimal-math-in-javascript.html#:~:text=In%20JavaScript%20all,up%20or%20down. – Steve Apr 13 '22 at 21:55

3 Answers3

0

You can not represent most of numbers precisely using floating point numbers, they will be off by a tiny bit all the time, so instead of comparing for equality you should compare difference to some epsilon.

function is_multiple(num, den) {
  return Math.abs(Math.round(num/den)-num/den) < 1e-15
}
console.log(is_multiple(0.0003, 0.0001))
mugiseyebrows
  • 4,138
  • 1
  • 14
  • 15
0

I'm no math wiz so take this with a grain of salt. This appears to be working for me. I tried all the example values in your post and they are all passing as multiples. May or may not work for all values.

const numA = 0.0005;
const numB = 0.0001;

if (Number.isInteger(Math.fround(numA / numB))) {
    console.log('is multiple');
} else {
    console.log('not a multiple');
}
tehbeardedone
  • 2,833
  • 1
  • 15
  • 23
0

Javascript has a problem with the float, watch this.

The solution is to multiply the two numbers by 10000 and perform the % operator on the integer.

you can retrieve the exponent to multiply by this way

const exp = num1.toString().split(".")[1].length

and multiply the number like this

num1 * (10**exp)
Alessio
  • 24
  • 2