TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Be careful with JS numbers

124 pointsby grenover 12 years ago

14 comments

crazygringoover 12 years ago
Essential rule: ALWAYS treat large ID numbers in JSON as strings. Produce them as strings on the server, so the browser treats them as strings during the JSON decoding process.<p>(Fortunately, if they're ID's where they need to stay exact, then you probably don't need to do any math on them! Although once a coworker of mine had to write a bitwise XOR function in JavaScript that operated on large ID numbers represented as strings. That was fun...)
评论 #5052018 未加载
wallflowerover 12 years ago
"Eich: No one expects the rounding errors you get - powers of five aren't representable well. They round poorly in base-two. So dollars and cents, sums and differences, will get you strange long zeros with a nine at the end in JavaScript. There was a blog about this that blamed Safari and Mac for doing math wrong and it's IEEE double -- it's in everything, Java and C"<p>-Peter Seibel Interview with Brendan Eich "who under intense time pressure, created JavaScript", Coders at Work, p.136
评论 #5051919 未加载
pcwaltonover 12 years ago
A lot of these issues are equally applicable to integer overflow (termination of loops and the "real web application disaster"). As a result, this is a deeper issue that extends beyond JavaScript into most languages—in general, programmers have to be aware that numbers in the runtime model of a language may not always work like you would expect theoretical, mathematical numbers to work.<p>Of course, floating point imprecision results in more surprising behaviors than integer overflow on the whole, but the danger is still there no matter what language you use (not counting the languages with full numeric towers, like Scheme).
jamestnzover 12 years ago
This is not the only area in JS where it pays to be careful with numbers.<p>For example, the parseInt function mentioned in the article actually does magic base determination. Your string will be parsed into a base-10 number, unless it begins with '0x' in which case base-16 is used, or if it begins with a leading '0' then it is treated as base-8.<p>This last case has stung me on several occasions when parsing user input into numbers: User puts a leading-zero, and you magically end up with octal conversions. (I believe this whole octal thing has been deprecated in recent JS implementations).<p>In any case it's sensible to specify the 'radix' whenever using the parseInt function, as in parseInt(numberString, 10);
评论 #5051660 未加载
评论 #5051694 未加载
评论 #5051938 未加载
0x0over 12 years ago
This bit a lot of twitter integrations hard, when tweet id's exceeded the non-lossy integer range of javascript floats.<p>All of a sudden, tweet ids got rounded off to point to completely different entries!<p><a href="https://dev.twitter.com/docs/twitter-ids-json-and-snowflake" rel="nofollow">https://dev.twitter.com/docs/twitter-ids-json-and-snowflake</a><p>Other JSON parsers may also be affected.
评论 #5051655 未加载
评论 #5052143 未加载
meatyover 12 years ago
This is one reason I stick to statically typed languages. I do a lot of work with cash values and without an explicit decimal type, the shit hits the fan when you hit a float issue.<p>I get a lot of flak on here for that opinion which is odd.
评论 #5051759 未加载
评论 #5051727 未加载
评论 #5052032 未加载
评论 #5051718 未加载
评论 #5051767 未加载
评论 #5051858 未加载
评论 #5053098 未加载
martin-adamsover 12 years ago
I got hit by JavaScript rounding on a project once. Funny thing is, IE8 was okay with it and Chrome was the one that caused issues.<p>Turns out that 1000000 * 8.2 = 8199999.999999999<p>Sometimes we learn the hard way. The bug was getting written into an XML document and pushed to an embedded device over HTTP which was expecting an int and caused the device to crash. We fixed both bugs.
评论 #5051852 未加载
评论 #5051849 未加载
Dylan16807over 12 years ago
1. IDs are strings, not numbers. This is the real problem twitter had. The ID size was only vaguely related to the number of tweets.<p>2. An event counter is not going to reach 2^50.
prophetjohnover 12 years ago
<p><pre><code> I have determined by experience that 9007199254740995 (which is 2^53+3) is the smallest not representable integer in Javascript. </code></pre> Here's something to drop in your browser console as an amusing illustration of this<p><pre><code> 9007199254740994 === (9007199254740995 - 1) </code></pre> and<p><pre><code> 9007199254740995 === (9007199254740995 - 1)</code></pre>
评论 #5051924 未加载
评论 #5051637 未加载
RyanZAGover 12 years ago
Interestingly, GWT gets around this problem entirely by having the 'long' datatype be created as two 32 bit numbers. Slows down calculation a little bit, but you get the correct values always.<p><a href="https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsCompatibility" rel="nofollow">https://developers.google.com/web-toolkit/doc/latest/DevGuid...</a>
评论 #5052087 未加载
shtylmanover 12 years ago
For people using npm, check out the 'int' and 'num' modules.
afhofover 12 years ago
Minor nit: isn't smallest integer not representable in JS -1000000000000000000000000000000000000 or something?
malkiaover 12 years ago
Is this in the JS standard, or is this in just some implementations?
评论 #5051943 未加载
rorrrover 12 years ago
&#62; <i>Javascript doesn’t have integer type but lets you think it has</i><p>Actually, JS has integer typed arrays.<p><pre><code> new Uint8Array([1,100,300]) [1, 100, 44] new Uint16Array([-1,2,300]) [65535, 2, 300] new Uint32Array([-1,2,300]) [4294967295, 2, 300] </code></pre> Here's the spec:<p><a href="https://www.khronos.org/registry/typedarray/specs/latest/#7" rel="nofollow">https://www.khronos.org/registry/typedarray/specs/latest/#7</a>