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

Fixing JSON decoding for Ints. #153

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
3 participants
@krisajenkins
Contributor

krisajenkins commented Feb 2, 2015

One way to check if a number is an integer in JavaScript is (value|0).
Sadly, this fails if the value is greater than 2^32, but still less than
Number.MAX_SAFE_INT.

This patch switches the Json decoder to use a polyfill of the proposed
ES6 Number.isInteger function.

@krisajenkins

This comment has been minimized.

Show comment
Hide comment
@krisajenkins

krisajenkins Feb 2, 2015

Contributor

Oops, sorry - that should read Number.MAX_SAFE_INTEGER.

Contributor

krisajenkins commented Feb 2, 2015

Oops, sorry - that should read Number.MAX_SAFE_INTEGER.

Fixing JSON decoding for Ints.
One way to check if a number is an integer in JavaScript is (value|0).
Sadly, this fails if the value is greater than 2^32, but still less than
Number.MAX_SAFE_INT.

This patch switches the Json decoder to use a polyfill of the proposed
ES6 Number.isInteger function.
@krisajenkins

This comment has been minimized.

Show comment
Hide comment
@krisajenkins

krisajenkins May 22, 2015

Contributor

This bug has just bitten me again, which in turn has nudged me to rebase against the current master branch. :-)

Contributor

krisajenkins commented May 22, 2015

This bug has just bitten me again, which in turn has nudged me to rebase against the current master branch. :-)

@ajhager

This comment has been minimized.

Show comment
Hide comment
@ajhager

ajhager Aug 1, 2015

Contributor

I have benchmarked and unit tested the original code, your proposed change, and a new method of my own design (original, proposed, and blend respectively below.) I used the tests from https://github.com/parshap/js-is-integer/blob/master/test.js and the benchmarks are at http://jsperf.com/isinteger-elm.

The original does indeed fail for values over and under 2147483647. proposed and blend are both correct, but blend is only slightly slower than the original in the general case and nearly equivalent in the typical case.

function original(value) {
  return typeof value === 'number' && (value|0) === value
}

function proposed(value) {
  return typeof value === "number" && isFinite(value) && value > -9007199254740992 && value < 9007199254740992 && Math.floor(value) === value;
}

function blend(value) {
  if (typeof value !== 'number') {
    return false;
  }

  if (value < 2147483647 && value > -2147483647) {
    return (value|0) === value;
  }

  return isFinite(value) && !(value % 1);
}    

No matter which function we go with, there needs to be some JSON tests to cover this. I would be happy to add those though.

Contributor

ajhager commented Aug 1, 2015

I have benchmarked and unit tested the original code, your proposed change, and a new method of my own design (original, proposed, and blend respectively below.) I used the tests from https://github.com/parshap/js-is-integer/blob/master/test.js and the benchmarks are at http://jsperf.com/isinteger-elm.

The original does indeed fail for values over and under 2147483647. proposed and blend are both correct, but blend is only slightly slower than the original in the general case and nearly equivalent in the typical case.

function original(value) {
  return typeof value === 'number' && (value|0) === value
}

function proposed(value) {
  return typeof value === "number" && isFinite(value) && value > -9007199254740992 && value < 9007199254740992 && Math.floor(value) === value;
}

function blend(value) {
  if (typeof value !== 'number') {
    return false;
  }

  if (value < 2147483647 && value > -2147483647) {
    return (value|0) === value;
  }

  return isFinite(value) && !(value % 1);
}    

No matter which function we go with, there needs to be some JSON tests to cover this. I would be happy to add those though.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 2, 2015

Member

@krisajenkins, thanks for providing a fix for this! I was not sure whether the behavior you expect is the behavior everyone would expect. If @ajhager agrees, I guess there is some sort of consensus :)

I'm trying this new thing out where I close issues more aggressively, even if they are a good idea that should happen. In this case, it seems like there are multiple folks who can do the updated fix, so to avoid a chance of blocking, can we do a new PR with the faster version and some tests?

Member

evancz commented Aug 2, 2015

@krisajenkins, thanks for providing a fix for this! I was not sure whether the behavior you expect is the behavior everyone would expect. If @ajhager agrees, I guess there is some sort of consensus :)

I'm trying this new thing out where I close issues more aggressively, even if they are a good idea that should happen. In this case, it seems like there are multiple folks who can do the updated fix, so to avoid a chance of blocking, can we do a new PR with the faster version and some tests?

@evancz evancz closed this Aug 2, 2015

@ajhager

This comment has been minimized.

Show comment
Hide comment
@ajhager

ajhager Aug 2, 2015

Contributor

I will do the new PR with tests.

Contributor

ajhager commented Aug 2, 2015

I will do the new PR with tests.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 2, 2015

Member

Awesome, thank you!

Also, sorry for the huge delay @krisajenkins, and thank you again @ajhager for unsticking things! :)

Member

evancz commented Aug 2, 2015

Awesome, thank you!

Also, sorry for the huge delay @krisajenkins, and thank you again @ajhager for unsticking things! :)

@krisajenkins

This comment has been minimized.

Show comment
Hide comment
@krisajenkins

krisajenkins Aug 2, 2015

Contributor

Cool, this'll be great to see. I'm decoding some JSON with some large productIDs, and having to manually meddle with elm-stuff keeps me awake at night. :-D

Contributor

krisajenkins commented Aug 2, 2015

Cool, this'll be great to see. I'm decoding some JSON with some large productIDs, and having to manually meddle with elm-stuff keeps me awake at night. :-D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment