9 ms·
999999999999999 - 999999999999997
- deleted 17y ago[deleted]
- swolchok 17y agoMaybe I'm just getting incurably academic, but I think "I found a bug!" is not nearly as interesting as "I found a bug!" and one of: 1) It affects millions of people! 2) It affects large amounts of money! 3) It is a great example of a new or rare class of bug. Here's how you can avoid introducing similar bugs into your code! Here's how we can detect these things automatically! etc. Here, the only thing that springs to mind is IEEE floating point being used internally by Google Calculator for some reason, which I find hard to believe. Where's the insight?
- kevindication 17y agoI guess it's just a reminder not to trust a search engine with your fiduciary responsibilities?
- jacquesm 17y agohttp://www.brillig.com/debt_clock/ http://www.brillig.com/debt_clock/ I think you still have a few orders of magnitude to go before that becomes a real problem.
- joshu 17y agoI remember a programmer once griping that you still need to be careful with floats, and that double-precision still did not have neough significant digits to store the dollar to turkish lira conversion rate..
- jacquesm 17y agoIf you need floats you don't understand your problem ;)
- calcnerd256 17y agounless you're doing realtime graphics
- jacquesm 17y agoNo, you can do realtime graphics just fine with fixed point arithmetic. You can do nice matrix and vector math entirely in 16.16 fixed point. It's not as fast as having a co-processor, but there was a time that those were not standard items.
- blasdel 17y agoThe problem is not with precision, but in using floats to represent money. Why in the fuck would you try to do financial math with anything but fixed-point or rational numbers?
- bdr 17y agoWhat about: 4) It's not obvious how this bug could happen! Let's think about it!
- swolchok 17y agoWell, apparently, it was obvious. AFAICT, no one has come up with a better explanation than using IEEE floating point where bignums should be used, which I pointed out in my original comment.
- dreish 17y agoExcept that neither double nor single precision IEEE floats behave the same way as whatever numbers Google is using.
- swolchok 17y agoThe algorithm probably first decides how to do the math and then does the math. EDIT: single-precision does behave this way: -bash-3.2$ cat precision.c #include <stdio.h> int main() { float f1 = 999999999999999; float f2 = 999999999999997; printf("%f\n", f1 - f2); return 0; } -bash-3.2$ gcc precision.c -bash-3.2$ ./a.out 0.000000 I am saying that if it's not consistent with single-precision across multiple inputs, there's probably code that looks at the numbers involved and decides what kind of numeric type to use to do the calculations. In this case, single-precision floating-point happens to be a bad choice. Second edit: replacing the 7 with a 6 still prints 0. The parent is right: something else is going on here. I like the theory espoused elsewhere in this discussion that it's a result of some truncation to avoid returning nonzero when the result should be zero.
- gjm11 17y agoWhat exactly do you mean, and how does it make "using floating point arithmetic with insufficient precision" a viable explanation for this, given that none of the usual floating-point formats behave in this way?
- 17y ago
- unalone 17y agoI was curious as to what caused this. Posting to HN seemed like the fastest way to get an answer.
- jacquesm 17y agoClearly someone wasn't using 'bignum' when they should have. Pretty sloppy to not even detect overflow on the input. another one: http://www.google.com/#q=999999999999999999+-+900000000000000000&hl=en&safe=off&sa=2&fp=7b823cb19394de08 http://www.google.com/#q=999999999999999999+-+90000000000000...
- tripa 17y agoIt's not really overflow. It's more like insufficient precision.
- jacquesm 17y agoInsufficient precision implies too little bits to store the number in. These are unsigned integers, they could have been represented as integers in a 64 bit unsigned value, if the number of bits in the variable destined to hold the input is not enough and you keep on working as though there are that's overflow al right. It should have simply thrown an error: operand too large. I have a dark brown feeling that it won't be long before it does though :)
- ars 17y agoThis bug has been there for years. So I don't think they'll fix it all that fast. They use floats for everything, not ints.
- jacquesm 17y agoThat would explain it quite nicely, the decimal64 implementation of the ieee floating point data tops out at 16 digits. edit: actually, it doesn't, the input above is 15 digits long.
- mustpax 17y agoThis is clearly a floating point precision problem. It happens when are no bits small enough on the mantissa to express the difference between the two values. Check out: http://www.google.com/search?q=999999999999999+*+1 http://www.google.com/search?q=999999999999999+*+1 this overflows into the next integer as well.
- deleted 17y ago[deleted]
- deleted 17y ago[deleted]
- mid 17y agoBTW, bing does it right: http://www.bing.com/search?q=999999999999999+-+999999999999997 http://www.bing.com/search?q=999999999999999+-+9999999999999...
- nostrademons 17y agoBing gets it wrong if you add enough digits: http://www.bing.com/search?q=999999999999999999999999999+-+999999999999999999999999997 http://www.bing.com/search?q=999999999999999999999999999+-+9...
- frossie 17y agoAs does the google calculator widget: http://www.google.com/ig/directory?hl=en&url=www.google.com/ig/modules/calculator.xml http://www.google.com/ig/directory?hl=en&url=www.google....
- DanielStraight 17y agoI agree. My first thought was "who cares?" After reading all the comments, my thought was "who cares?" Now, my thought is "who cares?"
- jey 17y agoSpoken like a true "business guy". It's technically interesting behavior.
- adrianwaj 17y agoIn the early 90's the Pentium floating point error could fit your criteria: http://www.cs.niu.edu/other/pentium.html http://www.cs.niu.edu/other/pentium.html I remember taking the chip into Digital at the time. They replaced it for me.
- keltecp11 17y agoI just want to know why you were even trying to calculate that figure in the first place?
- unalone 17y agoI found it on 4chan.
- profquail 17y agoI don't even want to know why it was posted there...
- unalone 17y agoThe thing about 4chan is that there's no order. That means not even chaos is an absolute must. Pictures of transsexuals and underage girls and people covered in fecal matter go alongside programming jokes, debates about Obama, and discussions of existentialism. This was closer to the latter. I don't go on 4chan often - once or twice a year at most - but when I do, it's to get that completely random mix of things all at once. Every time, I come away with 3-4 things I didn't know/hadn't thought of before. This was one of the things I found this time.
- jacquesm 17y agoI think I could have done without those mental images, thank you.
- randallsquared 17y agoThe ability to ignore and avoid thinking about certain things is essential when visiting 4chan. If you practice, you can read sentences like the above without having mental images of the described event. More advanced filters can prevent you from thinking about it with imagery even after seeing something you wish you hadn't seen. ;)
- icey 17y agoThis is a pretty good description of what's (probably) going on: http://www.stata.com/statalist/archive/2002-10/msg00290.html http://www.stata.com/statalist/archive/2002-10/msg00290.html
- RyanMcGreal 17y agoIn Python: >>> 999999999999999 - 999999999999997 2L
- swolchok 17y agoThe bug, in Python (needs more digits because Python's "float" is C's "double"): >>> float(999999999999999999) - float(999999999999999997) 0.0
- dreish 17y agoNot the same bug. Try chopping off a nine from each number, first in the above in Python, and then in the Google version.
- bfung 17y agoOut of curiosity... C:\>ruby --version ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] C:\>irb irb(main):001:0> 999999999999999 - 999999999999997 => 2 irb(main):002:0> 9999999999999999 - 9999999999999997 => 2 irb(main):003:0> 999999999999999.0 - 999999999999997.0 => 2.0 irb(main):004:0> 9999999999999999.1 - 9999999999999997.1 => 2.0
- martythemaniak 17y agoWolfram Alpha tells me the answer is two :p
- apotheon 17y ago. . . but it's copyrighted, so you're not allowed to tell anyone.
- briancray 17y agolol
- assemble 17y agoindeed
- datums 17y ago999 999 999 999 999 - 999 999 999 999 996 = 3 + or - 2 margin of error
- Que 17y agoWell you can also go somewhere meant for doing computations and get an accurate result. http://www.wolframalpha.com/input/?i=999999999999999+-+999999999999997 http://www.wolframalpha.com/input/?i=999999999999999+-+99999...
- deleted 17y ago[deleted]
- nixy 17y ago999 999 999 - 999 999 997 = 2 according to the calculator widget on the Dashboard in OS X 10.5
- zeantsoi 17y agoMS Excel had a similar issue (though probably an unrelated bug) a while back that caused a furor: http://www.appscout.com/2007/10/excel_bug_exterminated.php http://www.appscout.com/2007/10/excel_bug_exterminated.php Imagine being the accountant who learned about this too late...
- prakash 17y agoI bet the guys at blekko don't have this problem when they launch. http://www.skrenta.com/2008/04/microsoft_bias_in_msn_search_r.html http://www.skrenta.com/2008/04/microsoft_bias_in_msn_search_...
- joubert 17y agoObviously not using Lisp on the back-end.
- uninverted 17y agoI like Lisp too, but there's nothing especially accurate about it's arithmetic that you can't get in other civilized languages.
- joubert 17y agohttp://gigamonkeys.com/book/numbers-characters-and-strings.html http://gigamonkeys.com/book/numbers-characters-and-strings.h... One of the reasons Lisp is a nice language for math is its numbers behave more like true mathematical numbers than the approximations of numbers that are easy to implement in finite computer hardware. For instance, integers in Common Lisp can be almost arbitrarily large rather than being limited by the size of a machine word.3 And dividing two integers results in an exact ratio, not a truncated value. And since ratios are represented as pairs of arbitrarily sized integers, ratios can represent arbitrarily precise fractions.4 On the other hand, for high-performance numeric programming, you may be willing to trade the exactitude of rationals for the speed offered by using the hardware's underlying floating-point operations. So, Common Lisp also offers several types of floating-point numbers, which are mapped by the implementation to the appropriate hardware-supported floating-point representations.5 Floats are also used to represent the results of a computation whose true mathematical value would be an irrational number. Finally, Common Lisp supports complex numbers--the numbers that result from doing things such as taking square roots and logarithms of negative numbers. The Common Lisp standard even goes so far as to specify the principal values and branch cuts for irrational and transcendental functions on the complex domain.
- shiro 17y agoThese days quite a few languages already support bignums, rationals and even complex numbers. CL's support for these was unique back then, but I guess it has lost its edge in this domain. Still, support of strict read/write invariance of floating point numbers (e.g. as described in Burger&Dybvig 1996 and Clinger 1990) doesn't seem to spread widely outside CL/Scheme camp. Concept of exact/inexact numbers as well.
- Whippet 17y agoOn my HP48X rpn calculator I get = 0 The HP35 scientific calculator also give 0 as an answer. wierd.
- teeja 17y agoIs there anything that can do infinity - (infinity-1)?
- bdr 17y agoEven in non-standard models of arithmetic, where you could use infinity as an operand, the value of that expression would have to be undefined (not 1, as you seem to expect).
- Evgeny 17y agoMaybe we could just define "infinity = 999999" or something like that ...
- gloob 17y agoMaybe we could just define "zero = 123456789" or something like that while we're at it. If we're going to break math we may as well go whole hog.
- rbanffy 17y agoOne of my favorite pranks on Squeak was to do "true := false" in a workspace window. Sadly, it no longer works...
- leadnose 17y agoI've actually seen that kind of definition in the source of one game.
- calcnerd256 17y agoWhat about limit as x goes to infinity of x - (x - 1)? We do the algebra first, right? Now, that's a special case of y - (x - 1) where y = x, so can we get a different residue by going about the limit in two dimensions?
- modeless 17y ago
- gjm11 17y agoThis is definitely not just a matter of using double where something longer would have been better. 999999999999999 and 999999999999997 are both exactly representable as 64-bit IEEE floating-point numbers (i.e., doubles). They're not using single-precision floats either; with one 9 fewer in each number, everything's fine, but those numbers are way out of range for 32-bit IEEE floats. Doesn't look like fixed-precision decimals, either: reduce the second number by 1 and you correctly get a difference of 3.
- gjm11 17y agoTweaking that second number, I find that when the difference is 2 or less we get 0, but otherwise we get the right answer. More evidence that it's not simply a FP imprecision problem. Further, if I approximately halve them both (just change the initial 9 to a 4) then a difference of 1 or less produces 0 and other results are correct. I think what's going on is more likely this: whoever implemented this wanted to avoid giving nonzero answers to calculations whose correct answer is zero, and therefore put in some sort of deliberate truncation somewhere. (It's not clear to me exactly what -- maybe every addition or subtraction that produces an answer much much smaller than its inputs gets clamped to 0, or something.) I don't think the truncation is happening purely at the output stage: if I as it to do the original calculation and multiply the result by 100, e.g., I still get 0. (I had to write it like that because otherwise HN's asterisks-mean-italics hack scrambles it. Even though the supposedly matching asterisk is in a different paragraph. PG, if you're reading this, I'd love it if you were to change that behaviour.) In other words, I think we're seeing an unfortunate effect of the same feature that makes it say that cos(2*atan(1)) is 0 rather than reporting it as about 6.123 x 10^-17 (the actual result in IEEE doubles).
- perekk 17y agoRebol 2: >> 999999999999999 - 999999999999997 == 2.0 Rebol 3: >> 999999999999999 - 999999999999997 == 2
- kirubakaran 17y agoWell, they have fixed it.
- bmunro 17y agoNope, still equals zero.
- kirubakaran 17y agoOops my mistake!
- steiger 17y agoin bash: bash-3.1$ echo "(999999999999999 - 999999999999997)" | bc 2
- mace 17y agoIEEE 754 double precision can represent numbers with about 16 decimal digits of precision, however Google calculator (from anecdotal evidence) seems to only reliably represent numbers with 14 of precision (ex. http://www.google.com/search?q=99999999999999+-+99999999999997 http://www.google.com/search?q=99999999999999+-+999999999999...) Interestingly, for pure decimal operations it seems some other floating point representation is used. For example, http://www.google.com/search?q=1.0+-+0.2+-+0.2+-+0.2+-+0.2+-+0.2 http://www.google.com/search?q=1.0+-+0.2+-+0.2+-+0.2+-+0.2+-... returns mathematically correct result of zero. If double precision were being used it should return the mathematically incorrect result of 0.0000000000000000555 because of floating point representations errors.
- qeorge 17y agoBoth Yahoo[1] and Bing[2] get it right. [1] http://search.yahoo.com/search;_ylt=A0geu.i5PZNKqSoAurJXNyoA?p=999999999999999+-+999999999999997&y=Search&fr=yfp-t-150&fr2=sb-top&sao=1 http://search.yahoo.com/search;_ylt=A0geu.i5PZNKqSoAurJXNyoA... [2] http://www.bing.com/search?q=999999999999999+-+999999999999997&go=&form=QBLH&qs=n http://www.bing.com/search?q=999999999999999+-+9999999999999...
- psyklic 17y agoHere is what seems to have happened: Note that whenever the answer is not accurate, Google uses scientific notation. For example, 1e15 + 30 = 1.0 × 10^15. We accept this as true because Google only claims it is true to two sig figs. However, in this case, Google means to say 0.0 × 10^15, indicating two sig figs of accuracy. Google's mistake is probably that the internal notation used does not allow it to distinguish between "0" and "0.0 x 10^15", and so it does not report that the result is only accurate to two sig figs as it should. So, if Google somehow reports the "zero" result in scientific notation with two sig figs, then it will be consistent with the rest of their calculator and clear that it may not be an accurate result.