Incorrect math

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christoph

    Incorrect math

    alert( 100 * 1.15 );

    The above *should* show a value of 115. However, what I
    am actually getting is:

    114.99999999999 998

    alert( 100 * 1.10 );

    is showing as:

    110.00000000000 001

    Why?

    thnx,
    Christoph


  • Douglas Crockford

    #2
    Re: Incorrect math

    > alert( 100 * 1.15 );[color=blue]
    >
    > The above *should* show a value of 115. However, what I
    > am actually getting is:
    >
    > 114.99999999999 998
    >
    > alert( 100 * 1.10 );
    >
    > is showing as:
    >
    > 110.00000000000 001
    >
    > Why?[/color]

    JavaScript numbers are 64-bit floating point as specified in IEEE 754. It is the
    same representation that Java calls Double.

    The scheme is intended to preserve as much precision as possible, but it has
    some significant weaknesses. For example, it is not able to exactly represent
    common fractions such as 1/10 or 1/100. It can at best approximate them. As you
    can see, with a single operation you begin accumulating noticeable error. Also,
    be aware that the associative law and distributive law no longer apply.

    I think floating point is the wrong representation for numbers in most
    applications. However, it is extremely popular, and popularity is much more
    important these days than suitability or reliability. I recommend that in
    applications that require exactness (for example, when working with money) scale
    your values by a suitable factor (such as 100) so that all of your arithmetic
    will be on whole numbers, which are exact.

    See http://www.dcs.ed.ac.uk/home/mhe/plume/node9.html

    Comment

    • Michael Winter

      #3
      Re: Incorrect math

      "Christoph" wrote on 11/11/2003:
      [color=blue]
      > alert( 100 * 1.15 );
      >
      > The above *should* show a value of 115. However, what I
      > am actually getting is:
      >
      > 114.99999999999 998
      >
      > alert( 100 * 1.10 );
      >
      > is showing as:
      >
      > 110.00000000000 001
      >
      > Why?[/color]

      Floating-point values are traditionally represented in a structure
      with three parts: a mantissa, an exponent, and the sign. Each field
      has a fixed size. Immediately, that suggests limits. Furthermore,
      there are certain types of numbers that are difficult to represent
      accurately. Basically, there are flaws, and there are plenty of
      places to read about them on the Internet. This might not be quite so
      true of JavaScript as it is with, say the FPU on a PC, but it's at
      least a possible explanation.

      Because of this, it's usually not a good idea to do direct
      comparisons, and use ranges instead. Alternatively, round floating
      point values at certain points in the computation or before
      comparisons.

      Mike

      --
      Michael Winter
      M.Winter@[no-spam]blueyonder.co.u k (remove [no-spam] to reply)


      Comment

      • Fabian

        #4
        Re: Incorrect math

        Christoph hu kiteb:
        [color=blue]
        > alert( 100 * 1.15 );
        >
        > The above *should* show a value of 115. However, what I
        > am actually getting is:
        >
        > 114.99999999999 998
        >
        > alert( 100 * 1.10 );
        >
        > is showing as:
        >
        > 110.00000000000 001
        >
        > Why?[/color]

        Others have said why. The solutions are:

        Use whole numbers wherever possible

        Use Math.round() or Math.floor() immediately after any calculation
        involving fractions.


        --
        --
        Fabian
        Visit my website often and for long periods!


        Comment

        • Jerry Park

          #5
          Re: Incorrect math

          Christoph wrote:[color=blue]
          > alert( 100 * 1.15 );
          >
          > The above *should* show a value of 115. However, what I
          > am actually getting is:
          >
          > 114.99999999999 998
          >
          > alert( 100 * 1.10 );
          >
          > is showing as:
          >
          > 110.00000000000 001
          >
          > Why?
          >
          > thnx,
          > Christoph
          >
          >[/color]
          As subsequent posts noted, fractional arithmetic is problematic in
          floating point. Numbers which are finite in one base may be 'repeating'
          decimals in another. For the same reason you can't represent 1/3 exactly
          in base 10 as a fraction, other numbers which are exact in base 10 may
          be repeating in base 2.

          Either scaling the numbers in order to use only integer values or
          rounding the result will help.

          For example, in your example, the most precise value you have is
          represented to two decimal places. If you round the answer to two
          decimal places, you get the 'correct' answer.

          Comment

          • Dr John Stockton

            #6
            Re: Incorrect math

            JRS: In article <C7csb.618$Ob3. 657483@monger.n ewsread.com>, seen in
            news:comp.lang. javascript, Christoph <jcboget@yahoo. com> posted at Tue,
            11 Nov 2003 21:02:26 :-[color=blue]
            >alert( 100 * 1.15 );
            >
            >The above *should* show a value of 115. However, what I
            >am actually getting is:
            >
            >114.9999999999 9998
            >...[/color]

            One should always seek to read a newsgroup's FAQ before posting; it
            saves everybody a lot of trouble, the putative poster included. This is
            item 4.7 in ours.

            But read the whole FAQ, to avoid future problems; it points out,
            moreover, that comp.lang.java groups should not be used for javascript.
            In fact, AIUI, c.l.j.j has no legitimate existence. FU set.

            When questions in the FAQ are asked, the FAQ should be cited in answers
            even if it is felt that more explanation should be given in the case in
            question.

            --
            © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
            <URL:http://jibbering.com/faq/> Jim Ley's FAQ for news:comp.lang. javascript
            <URL:http://www.merlyn.demo n.co.uk/js-index.htm> JS maths, dates, sources.
            <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/JS/&c., FAQ topics, links.

            Comment

            Working...