0

I want a little timer which increases with the help of setInterval() the number in a html container. My code looks like this (jsfiddle):

var currentTime = 0;

window.setInterval(timer, 100)

function timer() {
    currentTime = currentTime + 0.1;    
    $('#time').text(currentTime);
}

Unfortunately this does not only add 0.1 each interval but add 0.1000001 (or something similar). Can someone explain me why?

damian
  • 5,314
  • 5
  • 34
  • 63

5 Answers5

3

Reason: This is because floating point can not be represented accurately in memory. There is always some rounding error.
Solution: You will have to work with integer, and when you have to show the time, divide the integer and then show the value till first digit after the decimal.
Like this:

var currentTime = 0;

window.setInterval(timer, 100)

function timer() {
    currentTime = currentTime + 1;    
    $('#time').text(currentTime / 10);
}

Fiddle: http://jsfiddle.net/2nLAc/1/
Further information: To knwo more about floating points, please see: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Ganesh Jadhav
  • 2,830
  • 1
  • 20
  • 32
  • Choose your answer as you've also provided a solution. Thanks a lot! Even though I'm using `toFixed(1)` now :) – damian Dec 12 '13 at 09:17
  • If you are going to use `toFixed()`, note that it returns the number in string format. I think then yoyo's way is the right way to use `toFixed()` – Ganesh Jadhav Dec 12 '13 at 09:34
1

This has to do with how decimal values are converted to binary floating point numbers. 1/10 turns into a repeating decimal in binary, so the number is not perfectly represented, and repeated operations can expose the error.

JavaScript uses IEEE-754 floating point numbers, for the record.

The the part after the decimal point) of Floating point numbers are stored as a sum of fractions. They are calcualted by adding a series of fractions. The order of the fractions is:

1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, ...

and then converted to binary.

Therefore the float can not be really exactly calculated.

Check this document

Igl3
  • 4,900
  • 5
  • 35
  • 69
1

You can also use the toFixed function to trim the long floats to just 2 decimal places. As shown below.

var currentTime = 0;

window.setInterval(timer, 100)

function timer() {
    currentTime = currentTime + 0.1;    
    $('#time').text(currentTime.toFixed(2));
}
Rakshitha
  • 31
  • 2
0

you could increase the currentTime with an integer and devide it when outputting

var currentTime = 0;

window.setInterval(timer, 100)

function timer() {
    currentTime++;    
    $('#time').text(currentTime/10);
}
Mark Homans
  • 637
  • 1
  • 6
  • 12
-1

Floating point calculation has some bug in javascript,you can fix this problem by using method toFixed.

 currentTime = (currentTime + 0.1).toFixed(1); 
yoyo
  • 722
  • 6
  • 4
  • Hey, that is no bug. Also, the limitation is not specific to Javascript. It applies to all the languages which use float. It is an implementation incapability. – Ganesh Jadhav Dec 12 '13 at 09:37