How does JavaScript handle integers?

- 1 answer



I have a snippet of code which allows a user to click on a 'variable (arbitrary) element', be prompted for a number, and see a processed version of that number produced in/on the element they clicked, based on a 'variable function'. I'll provide a more thorough description and the original code below. Skip to the bottom for the questions.

Thorough description

I have a function that looks like square(root) { return root * root; }. Obviously it takes a number and returns that number times itself. I've got another one like this printNum(input) { return input; } -Hopefully no explanation is needed.

The browser calls them with an event listener aimed at var element = document.getElementById("unique-key") which looks like element.addEventListener('click', promptFunction);.

And promptFunction uses var functionPlug =[functionsListedAbove]; to point input from window.prompt('inputvar') to element.innerHTML

Original Code

//where to write
var element = document.getElementById("module");

//what to write
var functionPlug = printNum;

//how to write
function square(root)      { return root * root; }
function printNum(input)   { return input * input / input; }

function promptFunction()  { element.innerHTML = functionPlug(window.prompt('inputvar')); }

//When to write
element.addEventListener('click', promptFunction);
//promptFunction(); --immediately
body {

 background-color: #3A3C3D; 		/*alt color #CCA #3A3C3D*/
 margin: 0;
 overflow: hidden;					/*top stop the extended shadow element height from causing the page to scroll*/

.backDrop {

 background-color: #FFF; 			/*alt colors #ACA null #CCA*/
 margin: auto;
 height: 100vh; width: 720px;
.backDrop:before {

 box-shadow: 0 0 20px black;
 position: absolute;
 height: 200vh; width: 720px;
 margin: auto;
 z-index: -1;

.lineBreak {

 height: 16px;

.module {

 border-left: 2px dotted red;
 border-radius: 5px;
 box-shadow: 0 0 5px -2px rgba(0,0,0,.4);
 margin: auto;
 height: 270px; width: 480px;
<body><!--All the comments you'll see below are meant to null 'white space' between layout elements--><!--
 --><div class="backDrop" id="backDrop"><!--
	 --><div class="lineBreak"></div><!--
	 --><div class="module" id="module"></div>

Now for my question

It seems that my square function works perfectly, but printNum has some very strange behavior I need explained to me.

input ranging from 9 to 9999999 produces the number you'd expect.

input 99999999 produces 99999998.99999999

input 999999999 to 9999999999 produces the numbers you would expect.

input 999999999999 produces 99999999999.00002

input 9999999999999 to 999999999999999 produces the number you'd expect

and finally 9999999999999999 produces 10000000000000000

That last one I think I understand because it's sixteen digits, but I'd still like to get out of the realm of speculation.

Are there other numbers the produce strange results? What are they and why do they do it? Also how can I avoid e notation?




Your text says printNum(input) { return input; }, but in the original code, there is function printNum(input) { return input * input / input; }. That is important.

The Question

So basically, you question can be summed up to why does javascript do this:

99999999 * 99999999 / 99999999 == 99999998.99999999
999999999999 * 999999999999 / 999999999999 == 99999999999.00002
9999999999999999 == 10000000000000000

BTW, the second one (with 999999999999) is not correct in my Chrome

The Answer

Many programming langauages make a clear distinction between an integer and a floating point number (because CPU does too). JavaScript does not. It has a Number type which is in fact a double-precision floating point (double in C), but looks like an integer whenever possible.

A floating point number can show much bigger numbers than integers and can have decimals, but it comes at the cost of losing precision, especially with big numbers.

You will want to know how big. You can check Number.MAX_SAFE_INTEGER. For number bigger than that, there is no guarantee that they will have the precision of an integer.

For example:

Number.MAX_SAFE_INTEGER == 9007199254740991
Number.MAX_SAFE_INTEGER + 1 == 9007199254740992
Number.MAX_SAFE_INTEGER + 2 == 9007199254740992

In your case, you have problems because:

99999999 * 99999999 > Number.MAX_SAFE_INTEGER
9999999999999999 > Number.MAX_SAFE_INTEGER


If you still don't understand why there is a problem with floating point numbers, see these:

Floating point inaccuracy examples