Is there a way to determine whether dividing one number by another will result in whole number in JavaScript? Like 18.4 / 0.002
gives us 9200
, but 18.4 / 0.1
gives us 183.99999999999997
. The problem is that both of them may be any float number (like 0.1, 0.01, 1, 10, ...) which makes it impossible to use the standard function modulo or trying to subtract, and floating point precision issues mean we will sometimes get non-whole-number results for numbers that should be whole, or whole-number results for ones that shouldn't be.

- 28,387
- 5
- 46
- 94

- 71
- 1
- 10
-
2Well, you could simply perform the division and see whether the result is an integer. Be careful with floats, though - you'll lose some precision and what should be an integer might actually just be very close. – Jul 27 '14 at 09:13
-
@MikeW that is the problem. I am not able to define the term: "very close". Just imagine the situation of dividing 18.4 by 0.1. Though 0.1 can not be represented precisely in floating-point, the result would never be 184 but something "very close". But how to recognize, whether it is close enough or not? – arahusky Jul 27 '14 at 09:17
-
@T.J.Crowder I meant divisible with no remainder :). Like 18.4 is divisible by 0.002, but 18.1 is not divisible by 1.03 – arahusky Jul 27 '14 at 09:18
-
When you use decimal points, the concept of reminder is meaningless. Isn't it? Everything is divisible by everything. – techfoobar Jul 27 '14 at 09:22
-
@arahusky: I've edited your question to say what I think you mean to say. Obviously, revert the edit if I've got it wrong. – T.J. Crowder Jul 27 '14 at 09:25
-
One hacky way would be a) convert both numbers to strings b) count the precision points (N) c) multiple with 10^N to make it non-floating point d) do modulo and get the result. – techfoobar Jul 27 '14 at 09:27
-
@techfoobar: Problem there is precision errors can still interfere. – T.J. Crowder Jul 27 '14 at 09:27
-
@T.J.Crowder - Yes, thats a definite possibility with standard JS FP math. OP will need better math tools/libs to be able to do it with precision I believe. – techfoobar Jul 27 '14 at 09:29
-
@T.J.Crowder - Since we're converting them to integers before doing any math (modulo), i think it actually will not cause errors. – techfoobar Jul 27 '14 at 09:32
-
@T.J.Crowder I edited your second example to 18.4 / 0.1. Because that should be divisible, but because of not precise representation of 0.1 does not result in integer number. – arahusky Jul 27 '14 at 09:32
-
@arahusky: It's your question (and they were your examples, in fact). I would have left the 18.1 / 1.03 example there to illustrate a case where you don't get a whole number, then used 18.4 / 0.1 to illustrate the precision issue. – T.J. Crowder Jul 27 '14 at 09:37
4 Answers
One hacky way would be
- Convert both numbers to strings with
toString()
- Count the precision points (N) by stripping off the characters before the
.
(including the.
) and taking the length of the remaining part - Multiply with 10^N to make them integers
- Do modulo and get the result
Updated Demo: http://jsfiddle.net/9HLxe/1/
function isDivisible(u, d) {
var numD = Math.max(u.toString().replace(/^\d+\./, '').length,
d.toString().replace(/^\d+\./, '').length);
u = Math.round(u * Math.pow(10, numD));
d = Math.round(d * Math.pow(10, numD));
return (u % d) === 0;
}

- 65,616
- 14
- 114
- 135
-
1“Multiply with 10^N to make them integers” If you could just multiply by 100 the floating-point number represented in decimal by X.XX to obtain the integer XXX, you wouldn't have the problem set by the question in the first place. The result is **likely** to be XXX because at least 100 is represented exactly in binary floating-point, but there still exist some values for which the result won't be an integer. See http://stackoverflow.com/questions/18031221/rounding-oddity-what-is-special-about-100/18036308#18036308 – Pascal Cuoq Jul 27 '14 at 10:10
-
You probably also want to round `u` and `d` to integers before computing `u % d`. To see why this is necessary, try `u=0.21` and `d=0.07`. – Mark Dickinson Jul 27 '14 at 10:26
-
Also, even ignoring the difficulties from the binary internal representation, the logic here is flawed. Consider `u = 7` and `d = 3.5`. You'll end up checking whether `7 % 35 === 0`. You want to multiply both values by the *same* power of 10. – Mark Dickinson Jul 27 '14 at 10:31
-
@MarkDickinson - You are right. This (wrongly) assumes both to be non-whole numbers. As i said, hacky and not very well tested and not fit for production. :-) – techfoobar Jul 27 '14 at 12:11
-
1It's nothing to do with whether `u` and `d` are whole numbers or not: you'll see the same issue for e.g. `u=0.20` and `d=0.04`. You could very easily fix your answer, though: just take the max of the two lengths computed, and scale both numbers by 10 raised to that power. (And add the rounding-to-integer step.) – Mark Dickinson Jul 27 '14 at 14:35
-
@MarkDickinson - Coming to think about it, thats a pretty basic mistake! Let me correct that.. – techfoobar Jul 27 '14 at 16:45
-
@MarkDickinson - Have edited it to multiply both with the greater precision value as well as rounding off to negate any (infamous .000000001) errors. :-) – techfoobar Jul 27 '14 at 16:49
I don't think you can do that with JavaScript's double-precision floating point numbers, not reliably across the entire range. Maybe within some constraints you could (although precision errors crop up in all sorts of -- to me -- unexpected locations).
The only way I see is to use any of the several "big decimal" libraries for JavaScript, that don't use Number
at all. They're slower, but...

- 1,031,962
- 187
- 1,923
- 1,875
I Assume that you want the reminder to be zero when you perform the division.
check for the precision of the divisor, and multiply both divisor and divident by powers of 10
for example
you want to check for 2.14/1.245
multiply both divident and divisor by 1000
as 1.245
has 3 digits precision, now the you would have integers like 2140/1245
to perform modulo

- 266
- 2
- 6
Divide first number by second one and check if result is integer ?
Only, when you check that the result is integer, you need to specify a rounding threshold. In javascript, 3.39/1.13 is slightly more than 3.
Example :
/**
* Returns true iif a is an integer multiple of b
*/
function isIntegerMultiple(a, b, precision) {
if (precision === undefined) {
precision = 10;
}
var quotient = a / b;
return Math.abs(quotient - Math.round(quotient)) < Math.pow(10, -precision);
}
console.log(isIntegerMultiple(2, 1)); // true
console.log(isIntegerMultiple(2.4, 1.2)); // true
console.log(isIntegerMultiple(3.39, 1.13)); // true
console.log(isIntegerMultiple(3.39, 1.13, 20)); // false
console.log(isIntegerMultiple(3, 2)); // false
Have a look at this for more details on floating point rounding issues: Is floating point math broken?