Forgot your password?

typodupeerror
Programming Math

What Every Programmer Should Know About Floating-Point Arithmetic 359

Posted by Soulskill
from the gaining-understanding-bit-by-bit dept.
-brazil- writes "Every programmer forum gets a steady stream of novice questions about numbers not 'adding up.' Apart from repetitive explanations, SOP is to link to a paper by David Goldberg which, while very thorough, is not very accessible for novices. To alleviate this, I wrote The Floating-Point Guide, as a floating-point equivalent to Joel Spolsky's excellent introduction to Unicode. In doing so, I learned quite a few things about the intricacies of the IEEE 754 standard, and just how difficult it is to compare floating-point numbers using an epsilon. If you find any errors or omissions, you can suggest corrections."
This discussion has been archived. No new comments can be posted.

What Every Programmer Should Know About Floating-Point Arithmetic

Comments Filter:
  • Analog Computers (Score:3, Informative)

    by Tisha_AH (600987) <Tisha.Hayes@gmail.com> on Sunday May 02 2010, @11:42AM (#32064180) Journal

    I seems to me that this problem would pop up any time you worked with an irrational number.

    Back in the early days the analog computer was used for things like ballistic calculations. I would think that they would be less prone to this type of problem.

    Linearity may still be an issue (analog systems have their own set of problems).

  • strictfp (Score:4, Informative)

    by lenmaster (598077) on Sunday May 02 2010, @11:56AM (#32064272)
    This article should mention strictfp in the section on Java.
  • by lenmaster (598077) on Sunday May 02 2010, @12:04PM (#32064334)
    If you think that every language except Java implements IEEE-754 to the letter, you are sadly mistakenly. That fact is Java can be used just fine for floating point work in most applications.
  • by Anonymous Coward on Sunday May 02 2010, @12:05PM (#32064342)

    You really need to talk about associativity (and the lack of it). ie a+b+c != c+b+a

    This is actually non-commutativity. Non-associativity means (a+b)+c != a+(b+c).

  • Re:Analog Computers (Score:5, Informative)

    by Anonymous Coward on Sunday May 02 2010, @12:07PM (#32064350)

    No, irrationality has nothing to do with it. It's a matter of numeric systems, i.e. binary vs. decimal. For example, 0.2 is a rational number. Express it in binary floating point and you'll see the problem: 2/10 is 1/5 is 1/101 in binary. Let's calculate the mantissa: 1/101=110011001100... (long division: 1/5->2/5->4/5->8/5=1,r3->6/5=1,r1->2/5->4/5->8/5...)

    All numeric systems have this problem. It keeps tripping up programmers because of the conversion between them. Nobody would expect someone to write down 1/3 as a decimal number, but because people keep forgetting that computers use binary floating point numbers, they do expect them not to make rounding errors with numbers like 0.2.

  • by abigor (540274) on Sunday May 02 2010, @12:08PM (#32064356)

    Actually, the linked article says exactly the opposite, and up above I posted a link to the JVM definition that verifies it. So you are 100% incorrect.

  • Before we get (Score:5, Informative)

    by toxygen01 (901511) on Sunday May 02 2010, @12:10PM (#32064374) Journal
    to floating point, please, everyone should've read Everything you ever wanted to know about C types [ibm.com] and part 2 [ibm.com] (which explains fp too).

    this will save a lot of time & questions to most beginning (and maybe mediocre) programmers.
  • by dr2chase (653338) on Sunday May 02 2010, @12:20PM (#32064466) Homepage
    Other issues that might be worth mentioning:
    • Catastrophic cancellation in complex arithmetic.
    • Single vs double rounding, in fused vs cascaded multiply-add operations.
    • Range reduction in trig functions (Intel hardware only uses a 68-bit PI, this causes problems sometimes).
    • Double-rounding when converting FP precision (e.g., 64-bit mantissa to 53, or 53 with extended exponent to 53 with regular exponent when the mantissa goes denorm).
    • Conversion to/from string representation.
    • Issues with "constructive reals" (a=b? is not necessarily an answerable question -- you might need to look at "all" the digits in order to answer "yes").
    • Distributive law DOES NOT HOLD -- a * (b+c) != a*b + a*c
  • by jjohnson (62583) on Sunday May 02 2010, @12:21PM (#32064474) Homepage

    >>> (1.0/3)*3
    1.0

  • by Anonymous Coward on Sunday May 02 2010, @12:23PM (#32064492)

    PLEASE stop this thread - interval arithmetic and all that has been around as a research topic for decades now.

    If you did not know: there are search engines providing lots of links...

  • by sdiz (224607) on Sunday May 02 2010, @12:32PM (#32064554)

    Java have a strictfp keyword for strict IEEE-754 arithmetic.

  • Re:I'd just avoid it (Score:5, Informative)

    by -brazil- (111867) on Sunday May 02 2010, @12:34PM (#32064576) Homepage

    The non-trivial problems with floating-point really only turn up in the kind of calculations where *any* format would have the same or worse problems (most scientific computing simply *cannot* be done in integers, as they overflow too easily).

    Floating-point is an excellent tool, you just have to know what it can and cannot do.

  • Re:Analog Computers (Score:3, Informative)

    by moonbender (547943) <moonbender AT gmail DOT com> on Sunday May 02 2010, @01:04PM (#32064796)

    True, but irrational numbers are those that cannot be written down exactly in *any* base

    ... except the irrational number's own base. ;)

  • Please look here (Score:5, Informative)

    by ctrl-alt-canc (977108) on Sunday May 02 2010, @01:18PM (#32064916)
    People interested into floating point math will find some very interesting materials and horror stories in the documents collected at the home page [berkeley.edu] of professor William Kahan, the man behind IEEE754 standard.
    According to my personal experience the paper by David Goldberg cited in the post isn't that difficult after all. Plenty of interesting materials can also be found in the Oppenheim & Shafer [amazon.com] textbook about digital signal processing.
  • by Dumnezeu (1673634) on Sunday May 02 2010, @01:27PM (#32065014)

    And wrong. I don't know how to use Github and if he won't bother to post an email address, I won't bother to learn about Github just for this.
    The comparison [floating-point-gui.de] page is wrong. Take nearlyEqual(0.0000001, 0) for example. As the author said, using Epsilon can be bad if you don't know what you are doing. The correct form of the function is:

    epsilon = 0.00001;
    function nearlyEqual(a,b)
    {
            return (Math.abs(b) < epsilon) ? (Math.abs(a) < epsilon) : (Math.abs((a-b)/b) < epsilon);
    }

    Also, parentheses don't hurt you and they help the reader.

  • by poopdeville (841677) on Sunday May 02 2010, @02:24PM (#32065458)

    Continued fractions are a straightforward way to implement exact computable real arithmetic. So yes, it's been used. And it's slow. But it is exact.

  • by Eharley (214725) on Sunday May 02 2010, @02:30PM (#32065492)

    I think the original poster was referring to this piece by the father of floating point, William Kahan, and Joe Darcy

    "How Java's Floating-Point Hurts Everyone Everywhere"

    http://www.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf [berkeley.edu]

  • by -brazil- (111867) on Sunday May 02 2010, @02:57PM (#32065680) Homepage

    In case you weren't just being funny, that == is correct, as it's meant to prevent NaN or Infinity results from the division, which can only happen with the actual "zero" values.

  • Oops! (Score:2, Informative)

    by Lord Efnar (30962) on Sunday May 02 2010, @03:31PM (#32065912) Homepage
    Well, so much for my smug mathy reply! Amusingly, the reason it worked so well is that my "Evaluate" statement asked Mathematica to symbolically evaluate the function prior to graphing. So, the graph looked nice because Mathematica was just graphing the "Abs[x]" function!
    Without the symbolic evaluation or requesting a particular precision level, the graph you actually get is this:
    http://www.untruth.org/~josh/real-rounding-oops1.png [untruth.org]
    You can get a more reasonable looking answer by messing with the calculation precision and accuracy...
  • by OSPolicy (1154923) on Sunday May 02 2010, @03:50PM (#32066032) Homepage

    Internal arithmetic always includes the exact solution, but only the rarest circumstances does it actually give the exact solution. For example, an acceptable interval answer for 1/3 would be [0.33,0.34]. That interval includes the exact answer, but does not express it.

  • by TheRaven64 (641858) on Sunday May 02 2010, @03:56PM (#32066078) Journal
    In the 1620, cited in the Wikipedia article that you mention, it wasn't just a way of doing arithmetic, it was the only way. It was a variable-word-length machine with 6-bit bytes, each storing one decimal digit or some flags, or a single character from a 64 character set. One special value indicated the end of a word.

    It didn't, however, as you imply, have BCD hardware. In fact, it had no hardware at all for arithmetic. At the start of the core memory, you had two lookup tables, one for addition and one for multiplication. To add two values together, you iterated over each pair of (decimal) digits, looking up their values in the table and then storing the result somewhere. If one of the digits had the carry bit set, then you did the same thing with the result of adding the next two digits together to add the extra one.

    The 1620 was nicknamed CADET by its designers for this reason - Can't Add, Doesn't Even Try. It was one of IBM's first attempts to make a cheap computer (you could buy a minimal unit for around $100,000 (paper tape instead of punch cards, only 10,000 characters of memory). It was the first computer my university ever bought, and the subject of an incredibly scathing review by Dijkstra.

  • by Anonymous Coward on Sunday May 02 2010, @04:44PM (#32066328)

    Interval Arithmetic does *not* produce exact solutions, it provides upper and lower error bounds on the calculation. Most IA implementations introduce a bias on every bounds calculation to insure that the "exact" result is proven to be bounded by the interval. I think some SPARC processors had IA support.

  • and Ada (Score:3, Informative)

    by krischik (781389) <krischik AT user ... rceforge DOT net> on Monday May 03 2010, @03:44AM (#32070020) Homepage Journal

    Correction: COBOL, PL/I and Ada. Ada has both fixed and floating point BCD arithmetic. And yes I too wonder why it is not in wider use. Perhaps it has to do with the ill conceived notion of "light weight languages" - most of which are not light weight at all any more once they are on the market for decade or so.

    Martin

Q: What do little WASPs want to be when they grow up? A: The very best person they can possibly be.

Working...