I recently encountered an issue that caused me a bit of confusion. JavaScript was not calculating a modulus in the same manner that Windows Calculator or Visual Basic was. At first I had thought this to be a bug, but after doing a bit more research I discovered that it was actually giving the correct answer and it was the Microsoft products that were giving me the wrong answer. To help illustrate this issue, open up your Windows Calculator and enter 1.47 MOD 0.05 and then look at the result. Now in your browser’s address bar enter javascript:alert(1.47 % 0.05); and press return. Notice the difference? Windows gives you a nice whole number to work with, and when you crunch the numbers in your head it makes sense.
So what’s the solution? It’s rather simple, actually. Since the issue only pops it’s head up when you’re working with decimals, all you have to do is multiply it by the correct power of 10 and then do your calculations. Once you have a result, divide it again by the same power of 10 and you have the answer. So for example, in Canada lately there’s been a lot of talk about the Royal Mint wanting to stop making pennies and as a result all transactions will be rounded to the nearest 5 cents. So lets look at a function that could be used to round a value down to a 5 cent increment:
// Enter a value in dollars and cents, such as 4.97 or 1.91 var value = prompt("Please enter an amount","Amount"); var balance_remainder = 0; var balance_sign = 1; if(isNaN(value)) { alert("Not a Number!"); value = 0; } else { // NOTE: JS calculates a modulus on floating point numbers differently than some languages // The solution is to multiply currencies by 100 before getting the modulus and then dividing the answer by 100 // Strip the negative off for now so it doesn't screw with the calculations if(value < 0) { balance_sign = -1; value = value * -1; } else { balance_sign = 1; } // Calculate the remainder balance_remainder = (value * 100) % 5; balance_remainder = balance_remainder / 100; // Strip off the remainder if(balance_remainder > 0) { value = value - balance_remainder; value = Math.round(value * 100) / 100; } // Re-sign the value value = value * balance_sign; } alert("Result: " + value);
And there you have it!
A seasoned Senior Solutions Architect with 20 years of experience in technology design and implementation. Renowned for innovative solutions and strategic insights, he excels in driving complex projects to success. Outside work, he is a passionate fisherman and fish keeper, specializing in planted tanks.