DEV Community

Cover image for Why Does JavaScript’s parseInt(0.0000005) Print “5”? 🤔
Jagroop Singh
Jagroop Singh

Posted on

Why Does JavaScript’s parseInt(0.0000005) Print “5”? 🤔

Why Does JavaScript’s parseInt(0.0000005) Print “5”? 🤔

JavaScript’s parseInt() function is quite handy for converting strings into integers, but it can sometimes lead to surprising results. One such mystery is when you call:

parseInt(0.0000005)
Enter fullscreen mode Exit fullscreen mode

And the output is 5! 😲

The Reason Behind It

Here’s the simple explanation: parseInt() doesn't just look at the number itself. It first converts the value to a string. So, when we pass 0.0000005, JavaScript automatically converts it to the string "5e-7". 🎢

Now, parseInt() starts reading the string from the left and stops at the first non-numeric character. In "5e-7", it sees 5 first, so it stops there and returns 5. It doesn’t process the scientific notation part (e-7), which is why it ignores the decimals.

Summary 📜

  • parseInt() processes numbers as strings.
  • It only reads up to the first non-numeric character.
  • The result is the integer before the first non-digit character.

Final Trick Question! 🧩

What will console.log(0.1 + 0.2 == 0.3) return? 🤨 Try it and see if you can crack this JavaScript mystery!

Top comments (31)

Collapse
 
miketalbot profile image
Mike Talbot ⭐

It's personally why I convert things into numbers using + rather than parsing. I don' have to remember or even know if it's a number or a string. My preference:

    const number = Math.floor(+someValueIWantToConvertToAnInt)

    // or often

   if(+someValue > 1) {}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jagroop2001 profile image
Jagroop Singh

Nice trick @miketalbot ,
Using the + simplifies conversion by implicitly handling type coercion, making the code more concise without needing explicit parsing.

Collapse
 
kmohzaid profile image
KMohZaid

Thankssaa

Collapse
 
whereisthebug profile image
@whereisthebug

Nice catch!

As you correctly pointed out, parseInt converts the number to a string. And JavaScript converts numbers to strings using scientific notation when the magnitude of the number (i.e. the number without the sign) is larger or equal than 1000000000000000000000 (21 zeroes) or smaller or equal than 0.0000001 (7 zeroes.)

Collapse
 
jagroop2001 profile image
Jagroop Singh

Exactly! @whereisthebug Do you know any other tricky things about JS?

Collapse
 
shifi profile image
Shifa Ur Rehman

What do you mean? I thought the whole javascript was a tricky thing 😂

Thread Thread
 
jagroop2001 profile image
Jagroop Singh

Image description

Collapse
 
moopet profile image
Ben Sinclair

This is another one of those issues which isn't an issue if you use the function as it's defined, and it's defined to take a string parameter. There's no reason I can think of to pass a float into it, you'd use an explicit cast or a dedicated function like Math.floor for that purpose.

Collapse
 
jagroop2001 profile image
Jagroop Singh

yes exactly !!

Collapse
 
john12 profile image
john

I don't know what's happening in JS. It is javascript bug or something else, okay I understand the concept of parseInt(0.0000005) thanks for explaining that but why console.log(0.1 + 0.2 == 0.3) returns False.

Also I think developers must know these edge cases points of js because somehow it will used in case of payments then it really hard to debug for begineers to debug

Collapse
 
jagroop2001 profile image
Jagroop Singh

@john12 ,
The behavior you're noticing isn't a bug, but a well-known quirk in JavaScript (and many other programming languages) related to how it handles floating-point arithmetic.

Image description

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

At least

parseInt("0.0000005")
// => 0
Enter fullscreen mode Exit fullscreen mode

but that is great catch I don't know about it ( I was never use parseInt )

Collapse
 
jagroop2001 profile image
Jagroop Singh

Yes, parseInt("0.0000005") returns 0 because parseInt stops parsing at the decimal point.
So , I thinks it's good to convert numbers to string before parsing into integer.

Collapse
 
works profile image
Web

That's cool, I already know about second one , what about this

console.log(null == undefined);

Collapse
 
jagroop2001 profile image
Jagroop Singh

That one is easy @works ,
== means loose equality that convert both values to a common type before comparing. So it returns true

If we usr === then it returns false

Collapse
 
works profile image
Web

Yes correct.

Collapse
 
boniface_gordian profile image
Boniface Gordian

This is such an interesting topic—parseInt() is one of those quirks in JavaScript that always surprises people! I really liked how you explained the behavior with the radix and how it defaults to 10 in most cases. It’s definitely one of those ‘gotcha’ moments for developers. Personally, I try to stick with Number() for clarity, but there are definitely cases where parseInt() shines. Have you ever run into unexpected issues with it in real-world projects? Great work on the article!

Collapse
 
jagroop2001 profile image
Jagroop Singh
Collapse
 
amerezhanyi profile image
A. Merezhanyi • Edited

That would be great you’d started with the history and mentioned that parseInt was designed to parse stings to numbers for cases like “10px” -> “10”, that explains a lot.
That worth mentioning that according to IEEE 754 all other programming languages do the same math and add a link to 0.30…4.com

Collapse
 
manchicken profile image
Mike Stemle

The 0.1+0.2===0.3 isn't a JavaScript issue, that's an IEEE 754 floating point math error. This is pretty common to a number of languages including JavaScript, Python, Perl, C/C++, etc.

Collapse
 
popbee profile image
Bernard Poulin

parseInt() is indeed handy when used correctly. Calling it with a number instead of a string would be considered a mistake.
If the intention was to convert a float into an integer, the popular quick hack is |0 as in 0.0000005|0. The more official way is to use Math.floor() obviously. parseInt() is simply the wrong method to do this.
Also note that negative values might or might not do what you'd expect. Depends on the use case.
I understand that the logic was maybe expecting a string and suddenly a number comes along at runtime and it was "working most of the time". The solution from Mike Talbot is indeed the best if you need to counter this issue. You can of course still combine it with the |0 hack

+0.0000005|0
Enter fullscreen mode Exit fullscreen mode
Collapse
 
peerreynders profile image
peerreynders

Bitwise OR is a flawed solution as its result is always a signed 32 bit integer (true of all bitwise operators except unsigned right shift which produces an unsigned 32 bit integer).

JavaScript's safe range for integers is much larger; Number.MAX_SAFE_INTEGER to Number.MIN_SAFE_INTEGER:

let max = 2_147_483_647;
let min = ~max;
console.log(max | 0); //  2147483647 ✔
console.log(min | 0); // -2147483648 ✔

max += 1;
min -= 1;
console.log(max | 0); // -2147483648 ✘
console.log(min | 0); //  2147483647 ✘
console.log(Math.trunc(max)); //  2147483648 ✔
console.log(Math.trunc(min)); // -2147483649 ✔

max = Number.MAX_SAFE_INTEGER;
min = Number.MIN_SAFE_INTEGER;
console.log(max); //  9007199254740991 ✔
console.log(min); // -9007199254740991 ✔

max += 2;
min -= 2;
console.log(max); //  9007199254740992 ✘ (i.e. loss of precision)
console.log(min); // -9007199254740992 ✘

// Bonus: More on loss of precision
const update = (value: number): [number, number] => [value, Math.trunc(value)];
let data = update(5.000000000000001);

const show = ([left, right]: [number, number]) => [
  left,
  Number.isInteger(left),
  right,
  Number.isInteger(right),
];
console.log.apply(undefined, show(data));
// 5.000000000000001,  false,  5,  true

data = update(5.0000000000000001);
console.log.apply(undefined, show(data));
// 5,  true,  5,  true
Enter fullscreen mode Exit fullscreen mode

And personally I prefer the explicitness of Number() coercion (e.g. Math.trunc(Number(0.0000005))) over the terseness of the unary plus operator.

Collapse
 
jagroop2001 profile image
Jagroop Singh

Thanks for sharing your views.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.