Why does "parseint(0.0000005)" return "5" in Javascript?

Asked

Viewed 271 times

9

Again, Javascript shows me a show of horrors magic and this time I want to know why this unexpected behavior while using the parseInt.

Why parseInt(0.0000005) returns 5 and not 0? How I get around this problem?

I would like a detailed explanation of this behaviour magical Javascript strange (at least for me).

console.log(parseInt(0.5))       // ok
console.log(parseInt(0.0005))    // ok
console.log(parseInt(0.000005))  // ok
console.log(parseInt(0.0000005)) // mágica

What’s interesting is that if it’s a string '0.0000005', the parseInt works as expected.

console.log(parseInt('0.0000005')) // ok
console.log(parseInt(0.0000005))   // mágica

  • 4

    That is indisputable: "Javascript shows me a horror show" - irrespective of the content of the question kkkk

  • 3

    @Bacco hahah really is. I laughed a lot when I discovered this kkkk

  • 3

    And the worst... imagine this in a system in production generating inconsistent results almost randomly?!?! Even identify the problem... How much is it parseInt(0.000001 / 2)? Ah, play 5

  • 7

    A footnote, to be the "devil’s advocate": The question leaves me divided, because parseInt is not to be used in number, for the beginning of conversation, after all, the only function of the parseInt is precisely "to obtain an integer of a string" (so much so that when it used string it worked out). If it is already numeric, it has no reason to use this function. At the letter, it is mere typo, the format is parseInt( string , base);), but I refrained from closing because I considered the "prank" side (treacherous by the way, but not exclusive to parseInt and yes to misuse of types).

  • 2

    @Bacco I understand your point, but I found it interesting to post for a reason that I identify myself. Imagine someone who starts studying JS, comes across this method parseInt, she uses with, for example, a string '1.08' and the return she has 1, Then that same beginner takes the test again, only with a number float 1.08, the return is the same, so that person can stay with the thought that "worked with numbers, so I can use with string and numbers without problems!", as I was. This little trick that is the X of the question. We must highlight do not use parseInt numbering!!!

  • 2

    @Bacco the purpose of the question was to expect an answer of why one should not use numbers with parseInt. I had even commented that I had not found anything to explain this here at Sopt, so I thought it would be of great value to the community and chiefly for those who are starting to study JS do not fall for this prank as I fall for.

  • 2

    I edited the answer emphasizing this question of not using parseInt with numbers :-)

Show 2 more comments

1 answer

14


According to the documentation, parseInt first converts the argument to string, and then evaluates this string.

This is also described in language specification, is the first thing that parseInt ago:

  1. Let inputString be Tostring(string).

Whereas string is the first argument received by parseInt

And what happens is that very small values, when converted to string, end up resulting in their representation in scientific notation:

let x = 0.05;
console.log(x.toString()); // 0.05
x = 0.0000005;
console.log(x.toString()); // 5e-7

And the string 5e-7 is interpreted as the number 5, because the algorithm of parseInt reads the digits, and when it finds a character that is not a valid digit, it stops and converts the digits read so far (and in this case, it is just the 5).


It is also worth remembering this rule:

  • If the input string Begins with "0x" or "0X" (a zero, Followed by lowercase or uppercase X), Radix is assumed to be 16 and the Rest of the string is Parsed as a hexadecimal number.
  • If the input string Begins with any other value, the Radix is 10 (decimal).

That is, if the string starts with 0x or 0X, it is assumed that the basis is 16 (if it has not been informed). In any other case, it is assumed that the basis is 10, and as the letter e is not a valid digit in base 10, Parsing only reads the digit 5.


In the case of string '0.0000005', this problem does not occur because this string, when converted to string, is not changed to scientific notation, remaining unchanged, and the Parsing is done by reading the zero and stopping at the point, resulting in zero.

Finally, as stated in the comments, the idea of parseInt - and also of parseFloat - is to do the Parsing of a string, resulting in the numerical value it represents. But if you are going to work directly with numbers, and not with strings, it is better to use mathematical functions for such.

If the idea was to take the whole part of the number, for example, the best thing would be to Math.floor(0.0000005) (or else Math.trunc, or Math.round, or some other function or calculation, depending on how you want to make the rounding). Use parseInt may even work in many cases, but as we have seen, it also hides some traps.


Finally, this problem also happens with very large numbers, which are also converted to a string in scientific notation:

let x = 10000000000000000000000;
console.log(x.toString()); // 1e+22
console.log(parseInt(x)); // 1

  • 3

    AI!!!....... I don’t want to program in JS anymore... :( Let’s create a tag bug-linguagem

  • I understood your answer, but how do I get around this bug?

  • @That’s another question, but one way would be x.toLocaleString('en', { maximumFractionDigits: 20 }) - should have other more beautiful (or not), so I think it depends on each case and need

  • 3

    @Actually I got confused, to make the whole conversion could be something like Math.floor(0.0000005), since you seem to be wanting to take only the whole part (rounding it down) - but again, the "best" solution depends on each case

  • 4

    And here I thought I knew all the tricks...

  • 6

    @Cmtecardeal The only lesson left is to use parseInt and parseFloat with String type parameters. They are meant to interpret strings and should not be used in other situations.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.