Precise calculations

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ladvánszky Károly

    Precise calculations

    Could anybody help me on how to do precise calculations with Python the way
    hand-held calculators do?

    A small example to show the impreciseness coming from the floating point
    arithmetics:

    (10000000000000 0.4*3)*100 gives 300000000000001 24.0

    Thanks for any help,

    Károly


  • Ben Finney

    #2
    Re: Precise calculations

    On Fri, 07 Nov 2003 13:17:44 GMT, Ladvánszky Károly wrote:[color=blue]
    > A small example to show the impreciseness coming from the floating
    > point arithmetics:[/color]

    Issues with representing floating point numbers in binary computers are
    discussed here with respect to Python:

    <http://www.python.org/doc/current/tut/node14.html>
    [color=blue]
    > Could anybody help me on how to do precise calculations with Python
    > the way hand-held calculators do?[/color]

    Use rounding, e.g. as implemented by the str() function. From the above
    URL:

    "Python's builtin str() function produces only 12 significant
    digits, and you may wish to use that instead. It's unusual for
    eval(str(x)) to reproduce x, but the output may be more pleasant to
    look at:
    [color=blue][color=green][color=darkred]
    >>> print str(0.1)[/color][/color][/color]
    0.1

    It's important to realize that this is, in a real sense, an
    illusion: the value in the machine is not exactly 1/10, you're
    simply rounding the display of the true machine value."

    --
    \ "I know when I'm going to die, because my birth certificate has |
    `\ an expiration date." -- Steven Wright |
    _o__) |
    Ben Finney <http://bignose.squidly .org/>

    Comment

    • Ben Finney

      #3
      Re: Precise calculations

      On 8 Nov 2003 08:26:07 +1050, Ben Finney wrote:[color=blue]
      > On Fri, 07 Nov 2003 13:17:44 GMT, Ladvánszky Károly wrote:[color=green]
      >> Could anybody help me on how to do precise calculations with Python
      >> the way hand-held calculators do?[/color]
      >
      > Use rounding, e.g. as implemented by the str() function.[/color]

      Apologies; str() doesn't do rounding per se, it shows the float values
      with fewer significant digits without changing the internal value.

      --
      \ "Once consumers can no longer get free music, they will have to |
      `\ buy the music in the formats we choose to put out." -- Steve |
      _o__) Heckler, VP of Sony Music, 2001 |
      Ben Finney <http://bignose.squidly .org/>

      Comment

      • Alex Martelli

        #4
        Re: Precise calculations

        Ben Finney wrote:
        ...[color=blue][color=green]
        >> Could anybody help me on how to do precise calculations with Python
        >> the way hand-held calculators do?[/color]
        >
        > Use rounding, e.g. as implemented by the str() function. From the above[/color]

        Use str if you really want to do like hand-held calculators, i.e., hide some
        digits. If you want really high precision in binary floating point, the
        gmpy extension module may be useful; if in decimal floating point, there is
        a class Decimal that's being worked on to eventually provide that, too.


        Alex

        Comment

        • Bengt Richter

          #5
          Re: Precise calculations

          On Fri, 07 Nov 2003 13:17:44 GMT, "Ladvánszky Károly" <aa@bb.cc> wrote:
          [color=blue]
          >Could anybody help me on how to do precise calculations with Python the way
          >hand-held calculators do?
          >
          >A small example to show the impreciseness coming from the floating point
          >arithmetics:
          >
          >(1000000000000 00.4*3)*100 gives 300000000000001 24.0
          >[/color]

          By coincidence I just posted a module (very alpha code, see "prePEP: Decimal data type" thread)
          that does exact decimal floating point, so you can do better than hand calculators ;-)

          First, let's use it to show what the full floating point bits ('all') show when converted
          to an exact representation:
          [color=blue][color=green][color=darkred]
          >>> from exactdec import ED
          >>> ED(100000000000 000.4,'all')[/color][/color][/color]
          ED('10000000000 0000.40625')
          ^
          +--the _actual_ floating point value represented
          [color=blue][color=green][color=darkred]
          >>> ED(100000000000 000.4,'all')*3[/color][/color][/color]
          ED('30000000000 0001.21875')
          ^
          +-- an exact multiple by 3
          [color=blue][color=green][color=darkred]
          >>> ED(100000000000 000.4*3,'all')[/color][/color][/color]
          ED('30000000000 0001.25')
          ^
          +--the exact value of the inexact floating point product
          [color=blue][color=green][color=darkred]
          >>> ED(100000000000 000.4*3,'all')* 100[/color][/color][/color]
          ED('30000000000 000125')
          ^
          +--times 100 exactly
          [color=blue][color=green][color=darkred]
          >>> ED(100000000000 000.4*3*100,'al l')[/color][/color][/color]
          ED('30000000000 000124')
          ^
          +--the result of the additional floating point multiply

          Now doing the math starting with an exact string literal for your starting value:
          [color=blue][color=green][color=darkred]
          >>> ED('10000000000 0000.4')[/color][/color][/color]
          ED('10000000000 0000.4')
          ^
          +--value is exact
          [color=blue][color=green][color=darkred]
          >>> ED('10000000000 0000.4')*3[/color][/color][/color]
          ED('30000000000 0001.2')
          ^
          +--product is exact (the right operand of 3 is converted like ED(3) which is exact
          since integer is exact.
          [color=blue][color=green][color=darkred]
          >>> (ED('1000000000 00000.4')*3)*10 0[/color][/color][/color]
          ED('30000000000 000120')
          ^
          +--similarly with the 100 factor, which is converted to exact before multiplying as well.

          Now try this on your calculator (note the binomial thing):
          [color=blue][color=green][color=darkred]
          >>> b = ED('10010010010 010010010010010 01')
          >>> b[/color][/color][/color]
          ED('1.001001001 001001001001001 001e27')[color=blue][color=green][color=darkred]
          >>> b*b[/color][/color][/color]
          ED('1.002003004 005006007008009 010009008007006 005004003002001 e54')[color=blue][color=green][color=darkred]
          >>> b*b*b[/color][/color][/color]
          ED('1.003006010 015021028036045 055063069073075 075073069063055 045036028021015 010006003001e81 ')

          ;-)

          Regards,
          Bengt Richter

          Comment

          Working...