Path: csiph.com!usenet.pasdenom.info!news.albasani.net!rt.uk.eu.org!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'example:': 0.03; 'value,': 0.04; 'yet.': 0.04; 'binary': 0.07; 'currency': 0.07; 'float': 0.07; 'subject:bug': 0.07; 'string': 0.09; '*is*': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'thread': 0.14; 'finite': 0.16; 'from:addr:behnel.de': 0.16; 'from:addr:stefan_ml': 0.16; 'from:name:stefan behnel': 0.16; 'is).': 0.16; 'operates': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:plane.gmane.org': 0.16; 'received:t-ipconnect.de': 0.16; 'rounding': 0.16; 'surprises': 0.16; 'tweak': 0.16; 'subject:python': 0.16; 'applies': 0.16; 'prevent': 0.16; 'wrote:': 0.18; 'wed,': 0.18; 'module': 0.19; 'trying': 0.19; 'stefan': 0.19; 'solution.': 0.20; 'seems': 0.21; 'header:User-Agent:1': 0.23; 'supported': 0.26; 'values': 0.27; 'header:X-Complaints-To:1': 0.27; 'header:In- Reply-To:1': 0.27; 'point': 0.28; 'appear': 0.29; 'points': 0.29; 'skip:( 20': 0.30; 'along': 0.30; 'gives': 0.31; '(unless': 0.31; '-0700,': 0.31; 'decimal': 0.31; 'steven': 0.31; 'languages': 0.32; 'supposed': 0.32; 'quite': 0.32; 'url:python': 0.33; 'cases': 0.33; 'limitation': 0.33; 'skip:d 20': 0.34; 'except': 0.35; 'there': 0.35; 'false': 0.36; 'subject:?': 0.36; 'url:org': 0.36; 'example,': 0.37; 'loss': 0.38; 'represent': 0.38; 'saves': 0.38; 'url:library': 0.38; 'to:addr:python-list': 0.38; 'to:addr:python.org': 0.39; 'either': 0.39; 'received:org': 0.40; 'above,': 0.60; 'mentioned': 0.61; 'numbers': 0.61; 'url:3': 0.61; "you're": 0.61; 'guarantee': 0.63; 'real': 0.63; 'such': 0.63; 'account': 0.65; 'beat': 0.68; 'design.': 0.68; 'subject': 0.69; 'results': 0.69; 'limit': 0.70; 'calculations': 0.84; 'cpu.': 0.84; 'received:87.139': 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Stefan Behnel Subject: Re: python 3.44 float addition bug? Date: Thu, 26 Jun 2014 07:53:52 +0200 References: <645be4a7-2e1b-44a4-9c45-9184c6df5518@googlegroups.com> <53ab8bc4$0$11121$c3e8da3@news.astraweb.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Gmane-NNTP-Posting-Host: p578ba676.dip0.t-ipconnect.de User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 In-Reply-To: <53ab8bc4$0$11121$c3e8da3@news.astraweb.com> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 44 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1403762045 news.xs4all.nl 2940 [2001:888:2000:d::a6]:53798 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:73607 Steven D'Aprano, 26.06.2014 04:56: > On Wed, 25 Jun 2014 14:12:31 -0700, Maciej Dziardziel wrote: > >> Floating points values use finite amount of memory, and cannot >> accurately represent infinite amount of numbers, they are only >> approximations. This is limitation of float type and applies to any >> languages that uses types supported directly by cpu. To deal with it you >> can either use decimal.Decimal type that operates using decimal system >> and saves you from such surprises > > That's a myth. decimal.Decimal *is* a floating point value, and is > subject to *exactly* the same surprises as binary floats, except for one: > which Decimal, you can guarantee that any decimal string you enter will > appear exactly the same (up to the limit of the current precision). > > For example: > > py> x = Decimal(1)/Decimal(23) > py> x > Decimal('0.04347826086956521739130434783') > py> x*23 == 1 > True > py> sum( [x]*23 ) == 1 # Surprise! > False > > py> (Decimal(19)/Decimal(17))*Decimal(17) == 19 # Surprise! > False It seems that no-one has mentioned the "fractions" module in this thread yet. It gives you rational numbers (enumerator/denominator), as supposed to the limited real numbers that floating point numbers represent. https://docs.python.org/3/library/fractions.html There are quite a number of use cases for exact calculations where rational numbers beat any other solution. For the cases above, for example, you'd get exact results by design. Or in currency calculations, where you want to move the rounding to the very end and prevent any loss of precision along the way (unless you're trying to tweak your account in the right direction, that is). Stefan