3
var metricUnits = function(num) {

console.log(num.toString().length);

};

// This works, gives me 21
metricUnits(900000000000000000000);

// But this fails, gives me 5
metricUnits(9000000000000000000000);

When I invoke this function, 21 is logged to the console. However, when I add one or more zeros to the end of my input argument, 5 is printed to the console?! Why is this?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Anna
  • 121
  • 1
  • 7

2 Answers2

5

If you logged the result to the console it would be obvious. Above a certain limit, numbers are represented by scientific notation (when asking for their string representation). In your second case, 9e+21 - 5 characters

Details of the limit can be found in this question.

Community
  • 1
  • 1
Jamiec
  • 133,658
  • 13
  • 134
  • 193
2

When the number is too big, it ends up looking like: 9e+21

So, when you do .toString().length, it will return 5.

An alternative way to count the number of digits to avoid the problem is:

var metricUnits = function(num) {
  log(Math.floor(Math.log10(num)) + 1);
};

log("900000000000000000000 =>");
metricUnits(900000000000000000000);  // 21
log("9000000000000000000000 =>");
metricUnits(9000000000000000000000); // 22

function log(msg) {
  document.body.insertAdjacentHTML(
    "beforeend",
    "<pre>" + msg + "</pre>"
  );
}
Vic
  • 8,261
  • 6
  • 42
  • 55
  • 2
    Sadly, `Math.log10` isn't in [the spec](http://www.ecma-international.org/ecma-262/5.1/), not even the [upcoming spec](https://people.mozilla.org/~jorendorff/es6-draft.html). Chrome and Firefox both have it; IE11 doesn't. – T.J. Crowder Jun 17 '15 at 13:16
  • 1
    I guess we'll have to work around it: http://stackoverflow.com/questions/3019278/how-can-i-specify-the-base-for-math-log-in-javascript – Vic Jun 17 '15 at 13:19