Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use parseInt instead of | operator for integer validation #147

Closed
wants to merge 1 commit into from

Conversation

jozanza
Copy link

@jozanza jozanza commented Nov 10, 2017

Seems like the | operator check will return a false negative given a sufficiently large integer. This PR solves #50

Seems like the | operator check will return a false negative given a sufficiently large integer
@@ -5,7 +5,7 @@ import isAbsent from './util/isAbsent';

let isNaN = value => value != +value

let isInteger = val => isAbsent(val) || val === (val | 0)
let isInteger = val => isAbsent(val) || val === parseInt(val, 10)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseInt isn't the right thing, here we don't want to coerce the value into a number. The reason the original code doesn't work with large ints, btw, is that JS really only has 32bit ints and the bitwise operators first convert the float to an int then truncate it. This leads to overflows in the large number case.

I'm a bit torn, the original method is more "correct" even if it does seemingly odd things. If we were gonna change it tho, we should use the Number.isInteger logic e.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger#Polyfill

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the coercion is fine if strict equality is being used (===)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But any approach that makes false negatives go away is fine by me 👍

Copy link

@sebpiq sebpiq Nov 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for @jozanza approach, parseInt + strict equality is everything that's needed, and it's more readable.

Copy link
Author

@jozanza jozanza Dec 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally realized the flaw of the parseInt approach:

9999999999999999999.9 === parseInt(9999999999999999999.9, 10)
// true

Numbers can't be that large in JS, so it's basically 10000000000000000000 === 10000000000000000000 after a certain point.

I'll work on adding the Number.isInteger logic to this PR when I get a chance @jquense

@jquense jquense closed this Apr 26, 2018
mAAdhaTTah added a commit to mAAdhaTTah/yup that referenced this pull request Dec 19, 2018
This works correctly for large numbers.

Related to jquense#147
mAAdhaTTah added a commit to mAAdhaTTah/yup that referenced this pull request Dec 19, 2018
This works correctly for large numbers.

Related to jquense#147
mAAdhaTTah added a commit to mAAdhaTTah/yup that referenced this pull request Jan 14, 2019
This works correctly for large numbers.

Related to jquense#147
mAAdhaTTah added a commit to mAAdhaTTah/yup that referenced this pull request Jan 14, 2019
This works correctly for large numbers.

Related to jquense#147
@vytch
Copy link

vytch commented Feb 14, 2019

parseInt('123456789a', 10) returns 123456789. Why not using type coercion: '123456789a' *1 . It is also 4 times faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants