3

alert(5.30/0.1);

This gives 52.99999999999999 but should be 53. Can anybody tell how and why?

I want to find that a number is divisible by a given number. Note that one of the number may be a float.

insertusernamehere
  • 23,204
  • 9
  • 87
  • 126
Rajeev Vyas
  • 182
  • 1
  • 6
  • 7
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Moritz Roessler Mar 13 '13 at 11:02

5 Answers5

9

For the same reason that

0.1 * 0.2 //0.020000000000000004

Some decimal numbers can't be represented in IEEE 754, the mathematical representation used by JavaScript. If you want to perform arithmetic with these numbers in your question, it would be better to multiply them until they are whole numbers first, and then divide them.

shanet
  • 344
  • 2
  • 7
8

Scale the numbers to become whole. Then modulus the result.

alert((5.30*10) % (0.1*10));
DickieBoy
  • 4,886
  • 1
  • 28
  • 47
0

You can get it by following: var num = (5.30/0.1); alert(num.toFixed(2));

this will give you 53.00.

PM.
  • 1,735
  • 1
  • 30
  • 38
  • The question says "*i want to find that a number is divisible by a given number*", presumably this means "exactly divisible". If you discard everything after the decimal point then every negative result will come out as a false positive. – Quentin Mar 13 '13 at 11:05
  • @Quentin See the first line: This gives 52.99999999999999 but should be 53. Can anybody tell how and why? – PM. Mar 13 '13 at 11:08
  • — See the second line. "*I want to find that a number is divisible by a given number.*". Your answer addresses only the first line without taking the context into account. The context is important. – Quentin Mar 13 '13 at 11:30
0

Now that you have read the article i commented, you should know the root of your problem. You can partially work around that by scaling you floats...

Then just write a function which:

  • If its a float
    • Scale the Numbers
  • return a boolean representation of the divisibility of the number

function isDivisable(n, d) {
    var ndI = 1 + "".indexOf.call(n, "."); //Index of the Number's Dot
    var ddI = 1 + "".indexOf.call(d, "."); // Index of the Divisors Dot
    if (ndI || ddI) { // IF its a float
        var l = Math.max(("" + n).length - ndI, ("" + d).length - ddI); //Longest Decimal Part
        var tmpN = (n * Math.pow(10, l)); //scale the float
        var tmpD = (d * Math.pow(10, l));
        return !~((tmpN % tmpD) - 1); //Substract one of the modulo result, apply a bitwise NOT and cast a boolean.
    }
    return !~((n % d) - 1); // If it isnt a decimal, return the result 
}
console.log(isDivisable(5.30, 0.1));//true

Heres a JSBin

However...

As Integers are stored with 64bit precision, the maximum precision lies about (2^53), and you will soon exceed the maximum precision when scaling larger numbers.

So it might be a good idea to get some sort of BigInteger Library for javascript if you want to test floats for divisibility

Moritz Roessler
  • 8,542
  • 26
  • 51
-1

To find if a number x is divisible by a number y you have to do x % y (modulo). If the result is 0, it is perfectly divisible, any other isn't.

Andrei Nemes
  • 3,062
  • 1
  • 16
  • 22