-
Notifications
You must be signed in to change notification settings - Fork 687
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
Patch SBJsonStreamParser for integral values. #171
Conversation
SBJsonStreamParser parses an integer into an NSDecimalNumber. With some large values, such as Twitter tweet ids, this results in a rounding error. This pull request makes a one line change to the parser to parse into a longLongNumber instead of a decimal number. It also modifies the sample app to use the Apple social media APIs and accounts. The problem can be demonstrated by uncommenting the original line in the SBJsonStreamParser file. Then the app will start logging tweets that have incorrect values for tweet ids.
Hi Andrew, I'm a little confused about your statements above. Here's Apple's description of NSDecimalNumber:
AFAIK you cannot rely on
Could it be that the way you are reading from the NSDecimalNumbers is causing the rounding you're seeing? |
Stig, My patch fixes a real, demonstrable problem with interpreting twitter ids as an NSDecimalNumber. It includes modifications to your example code that shows the problem with live data. If you revert the fix to SBJsonStreamParser, the problem is revealed in the log statements. You may have a better way to fix it than my one line patch. Regardless, I've surfaced a problem in your current scheme. The NSDecimalNumber is introducing a rounding error to some twitter ids. At minimum, the test coverage is incomplete. While NSJSONSerialization is far from the gold standard in JSON parsers, they do return an NSNumber for this parameter. You may wish to revisit your implementation decision. Andrew |
You're right. There is definitively something fishy going on here. It's weird; it almost looks like a bug in NSDecimalNumber itself because it stringifies correctly:
but we get an off-by-one for longLong (and unsignedLongLong) values:
In contrast, for the id_str, we get:
What. Is. Going. On? Double-precision IEEE floating point, is what. It looks like NSDecimalNumber's conversion to So yes; you were right. My tests were inadequate. NSDecimalNumber has been a sticking point for a while (see issue #128). This might provide motivation to finally remove it. Let me mull this over over the weekend. |
…per integer type Integers are now always parsed into `long long` or `unsigned long long` if they fit.
Manually merged. |
Stig, As the TwitterStream app is now officially broken by Twitter's move to the new API, I suggest you adopt my patches to that app or equivalent. Andrew |
I already did earlier today. Thanks! Stig Sent from my iPhone On 22 Jun 2013, at 17:03, "Andrew W. Donoho" notifications@github.com wrote:
|
SBJsonStreamParser parses an integer into an NSDecimalNumber. With some
large values, such as Twitter tweet ids, this results in a rounding
error. This pull request makes a one line change to the parser to parse
into a longLongNumber instead of a decimal number. It also modifies the
sample app to use the Apple social media APIs and accounts. The problem
can be demonstrated by uncommenting the original line in the
SBJsonStreamParser file. Then the app will start logging tweets that
have incorrect values for tweet ids.