Why Do Computers Suck at Math?

Maybe this is the reason why this cheap calculator I bought a few weeks ago does some calculations completely wrong. 2060/3.8*3.8=1 according to that piece of crap. Even other cheap calculators don’t have that problem.

crap I still remember when stupid int counters would overflow at 32k and unsigned shorts were 256.

As Dennis mentioned above, 0.1 is a simple base 10 fraction that has a repeating form in base 2, i.e., 0.0(0011) where the part in parentheses repeats. 0.3 is another example: 0.0(1001). Thus, they cannot be exactly represented in IEEE arithmetic. I’ve made some base conversion tools for numbers with fractional parts available at

http://www.knowledgedoor.com/1/Base_Conversion/Convert_a_Number_with_a_Fractional_Part.htm

These can be very helpful in illustrating just how easy it is to run into numerical problems when switching between base 10 and base 2 representations.

Computers only suck at math when they don’t use IBM COBOL packed decimal (BCD) fields ^^

I hate to sound off on that, but it isn’t a very simplified way of looking at 0.99999… vs. 1, that’s a wrong way of looking at 0.99999… vs. 1. Because the point is that they are literally the same number expressed in two different ways. Not so close as makes no difference, but the exact same number.

Hmmm… hehehehe… Ok, engineer… Take 1.0. Subtract your number0.99999. Test for ‘zero’ and if it passes the test, when you are between the moon and Mars, you are right, and complete your mission. if you are wrong, you find temperatures in the solar range, and you … should go to the sun when it is night.

The numbers are the same, by convention, NOT mathematics. People did not deal with such long decimals in olden times. (when the rules of mathematics and arithmetic were developed.)

Better still… make a gamble out of it. If the odds are that you have a 0.999999… chance of surviving an ordeal, you might take the bet… But, the odds are not 1.0… not a certainty. Would you still chance the bet? Murphy wrote the laws. The important one was ‘at the worst possible time’… If certainty is required, 1.o is NOT equal to .99999…

To support precise math and to have it built in is two different things. C++ supports arbitrary precision math just fine when using GNU MP Bignum lib http://gmplib.org/, it just isn’t java which has even kitchen sink built in

I do agree that infinite precision math is required in end-user applications (besides maybe matlab/mathcad and alike).

One can easily guess that Jeff is a little biased against Microsoft by not finding in his post this link
http://search.live.com/results.aspx?q=399999999999999-399999999999998mkt=en-US

And this link http://blogs.msdn.com/oldnewthing/archive/2004/05/25/141253.aspx

Ruby did not exist and and Google was a very small startup when Microsoft fixed this bug.

Unlike strange floating point caluclation, 850*77.1 trick in Excel was a real bug. Fortunately, I’ve just tried that trick in Excel 2007 SP2 and could not reproduce the issue.

Within the real number system, ‘0.999…’ is, by definition, equal to the real number ‘one’.

In other number systems things can be defined differently:
http://en.wikipedia.org/wiki/0.999…#Alternative_number_systems

As far as I know systems are ‘best effort’ approximations of reality.

You are making a ‘modern’ assumption based on incorrect data.

Unless proper correcting software is included, computers are terrible at math. They can do it in binary, octal and hexidecimal. Unfortunately, they can not do decimal math. (There is NO octal equivalent to decimal 0.05… period. Also, there is a major difference between negative zero (-0.00) and positive zero (0.00). Control Data used to manufacture a decimal computer, and these problems were not really a question. Since the Window take over of reality, precision decimal math has taken a back seat to ‘enhancements’ instead of true and accurate function.

In the olde tymes (when BAL and machine language were the only languages, and punch paper tape was high speed input… Computers had to have math functions programmed (oftentimes) since, if you really know the facts, computers can only add.

Writing functions to actually do math correctly, is a lost art. After all, Computers are great at multiplying and dividing!! Right!!!.. er… ummm…

No. They aren’t. Not unless a human, with understanding and knowledge, fixes the basic problem… Computers are binary, and Binary, Converted to octal, doesn’t function in decimal.

Launch a space ship, from earth, to … Ummm. Mars… The error in the system, unless corrected for (have you ever heard of mid missions flight corrections??) will miss Mars, and not by a small factor.

Unary mathematics is almost unheard of, now days… I remember a thick tome that was required reading, to do flight plotting. Seems a negative zero will, according to the computer either be equal, or not equal to positive zero, unless Murphy said it ain’t, and you better listen.

Mathematically speaking, if the remainder of a subtration is even 0.000… (999 more zeroes)…01, there is a difference. Unless the difference is zero (positive or negative) there is a difference! If there is a positive or a negative zero, they you have to know why and test to see IF the difference is significant. Not doing so, will create errors like you might not believe.

Hmm…

einstein:~ siuying$ irb
irb(main):001:0 399999999999999-399999999999998
= 1
irb(main):002:0 12.51-12.52
= -0.00999999999999979
irb(main):003:0 quit

einstein:~ siuying$ python
Python 2.5.1 (r251:54863, Jan 13 2009, 10:26:13)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type help, copyright, credits or license for more information.
12.51-12.52
-0.0099999999999997868

Since nobody mentioned Haskell so far: Haskell is another language that handles large numbers and fractions very well. It even has a rational number datatype that represents numbers as the quotient of two integers of arbitrary size.

@the old [o]rang:

A simple way (very simplified) is to say that 0.99999… is so close to 1.0, that I wish not to have to print all them darned nines, and for my purposes I will round it off to 1.0, so I don’t have to spend all day writing out senseless nines. The precision of avoiding the incredibly small differences is not worth the effort, since each space is 1/10 the size of the previous.

At the risk of enabling a troll, let me correct you.

0.999… is not pretty close to one. It is one. Not by convention, not by habit, not by agreement, not by tradition, not by laziness. The problem here, I think, is that you are ignoring what that … means. It doesn’t mean a whole bunch more, nor an arbitrarily large number of. It means an infinite number of. It means they go on forever. Not till you get tired of writing them, or holding down the 9 key. For. Ever.

What’s more, your rambling about positive zero and negative zero, about how computers can only add, the rest is just tricks, and computers can’t do anything but binary make me think you’re a representative from the Time Cube organization. Look up bignums and BCD and get back to us. (Or don’t.)

In general, to the commenters who are saying that Jeff is speaking to the wrong crowd…

It’s good that you had an excellent computer science education. But you seem to be failing to account for the common nature of these issues. Maybe Jeff is saying things that have already been said, but as long as these mistakes keep happening these things bear repeating. At the very top of the article, it’s observed that Google has made this common, easily-corrected error (I say easily-corrected because with Guido van Rossum in their organization somewhere, you’d think they could make the search engine’s math output at least as good as the default handler in Python). If Google’s screwing up something this simple, maybe it’s not as obvious to the average programmer as we think it is?

So perhaps the people who write common and widely-used software should improve their computer science education. And perhaps the people who comment on these articles should (http://drupal.org/node/29405) help by contributing to successful projects like Drupal.

Maybe computer science prowess and popular, successful programs are semi-independent variables.

And maybe in a world where they are semi-independent, the people who know what they are doing should get up off the backs of the people who try to educate the rest of us.

The only problem I have with the .99999… = 1 is that give me N number of 9’s after 0.9 and I can give you an infinite number of number between that number and 1. Not necessarily on a computer but in theory.

You know the old saying … garbage in, garbage out

Don’t blame the poor unknowing computer. It’s just doing what it’s told, and following the rules its given to produce a result.

Trickiest computer math gotcha I stumbled upon in reality: modulo repetition. Given a float x, think there’s no difference between x%1 and x%1%1 (% being modulo operator)? Think again:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18)
[GCC 4.3.3] on linux2
Type help, copyright, credits or license for more information.
x=-1e-20
x%1
1.0
x%1%1
0.0

Jolly good. If you see somebody using floating point for currency representation, they surely don’t know what they’re doing. Beware bad text-books.

Decimal numbers are coming back to computers. There is a modern IEEE-standard for them, and hardware support is said to be coming for this standard. Even the software versions are actually quite fast, but most importantly, they’re correct. There are implementations for C and C++ as well.

Mike Cowlishaw made the programming language REXX which actually uses decimal numbers, and he’s done some important work on decimal numbers and the IEEE-standard. He’s also the man behind the JSR-13 for BigDecimal in Java. Densely Packed Decimal numbers are a variance of Chen-Ho encoded decimal numbers.

Some links on decimal arithmetic on computers for those who are interested:

http://domino.research.ibm.com/comm/research_people.nsf/pages/cowlishaw.index.html
http://en.wikipedia.org/wiki/Mike_Cowlishaw
http://www.intel.com/technology/itj/2007/v11i1/s2-decimal/1-sidebar.htm
http://en.wikipedia.org/wiki/Densely_Packed_Decimal
http://speleotrove.com/decimal/
http://speleotrove.com/decimal/DPDecimal.html

Simply put: There is not much excuse for not doing math correctly on computers. I can understand why floating point arithmetic is wanted by Fortran/HPC/Science programmers, who at least for some systems need as much speed as they can get their hands on, but for anything else, decimal arithmetic is the way to go.

Anyway, it’s a bliss to use a language which just does it correctly.

@zokier

So if Java is like a house, then C++ is like a house without a kitchen sink?

Sounds about right to me… :wink:

So…you’ve found a problem. What’s the solution?

In mathematics, the repeating decimal 0.999Ö denotes a real number equal to one. In other words: the notations 0.999Ö and 1 actually represent the same real number.
This equality has long been accepted by professional mathematicians and taught in textbooks.

Really? Glad to know it gets taught; nobody taught that to ME. I swear, just a couple of months ago I was randomly thinking about periodic fractions and non-decimal bases (nothing better to think about… maybe that’s why it took me so long to get married :slight_smile: ), and I stumbled upon this fact in total bewilderment. It was a clear, unmistakable and inescapable consequence of a few basic mathematical facts. How fun!

To me, the most interesting consequence is that our conventional numeric notation system (even with the use of … or the vinculum sign) is not a biyective representation of the set of Reals, even though for the longest time I had assumed it was.