Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange rounding problem

0 views
Skip to first unread message

Marc

unread,
Mar 14, 2003, 6:40:52 PM3/14/03
to
Hi all,

I have a number that slightly changes value at different points. I
haven't been able to find any information on how to "stabilize" it.
Here's the code snippet:


... in function getGap ...
if gap <= .00000096:
gap = .00000096
print "GAP IN ROUTINE " + str(gap)
return [list, float(gap), self.slotID]

... call to function...
gapList = slot.getGap(iteration, size)
print "GAP BEFORE CONVERSION " + str(gapList[1])
gap = int(gapList[1]/pow(10,-9))
print "GAP AFTER CONVERSION " + str(gap)
print "gapList = " + str(gapList)

... output ...
GAP IN ROUTINE 9.6e-007
GAP BEFORE CONVERSION 9.6e-007
GAP AFTER CONVERSION 959
gapList = [[], 9.5999999999999991e-007, '3']


This appears to be confusing. The variable is set to .00000096 but is
passed through as 9.5999999999999991e-007. It appears accurate when
printed before the value is returned, is inaccurate when the full
return list is printed, accurate when it's printed by itself after the
return, and then inaccurate again when the division is made. Why does
it do this, and how can I avoid it?

Thanks,
Marc

Irmen de Jong

unread,
Mar 14, 2003, 6:44:42 PM3/14/03
to
Marc wrote:

> This appears to be confusing. The variable is set to .00000096 but is
> passed through as 9.5999999999999991e-007. It appears accurate when
> printed before the value is returned, is inaccurate when the full
> return list is printed, accurate when it's printed by itself after the
> return, and then inaccurate again when the division is made. Why does
> it do this, and how can I avoid it?

You can't avoid it. It's a property of floating point numbers,
not of Python. More info in the FAQ;
http://www.python.org/cgi-bin/faqw.py?req=show&file=faq04.098.htp

--Irmen

Mike Meyer

unread,
Mar 15, 2003, 11:33:28 AM3/15/03
to
mnat...@airmail.net (Marc) writes:

> GAP IN ROUTINE 9.6e-007
> GAP BEFORE CONVERSION 9.6e-007
> GAP AFTER CONVERSION 959
> gapList = [[], 9.5999999999999991e-007, '3']
>
> This appears to be confusing. The variable is set to .00000096 but is
> passed through as 9.5999999999999991e-007. It appears accurate when
> printed before the value is returned, is inaccurate when the full
> return list is printed, accurate when it's printed by itself after the
> return, and then inaccurate again when the division is made. Why does
> it do this, and how can I avoid it?

Actually, all the numbers are the same. What you are seeing is the
difference between str and repr. Repr is used on the elements of a
list when it is printed. But here's what happens when you do things by
hand:

>>> print repr(9.6e-7)
9.5999999999999991e-07
>>> print str(9.6e-7)
9.6e-07
>>> print str(9.5999999999999991e-07)
9.6e-07
>>>

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Marc

unread,
Mar 15, 2003, 12:34:20 PM3/15/03
to
I have another question for the penguins. I understand now how this works.
I'm a little confused as to why. I'm sorry If I'm going over retreat ground,
but I can't find a good explanation of this anywhere.

I completely understand that if you evalute 1/3 then you get a number that
goes off into infinity asymptotically approaching a value of 1. And then
when you evaluate that number the system will print as many numbers as you
can handle, and then round.

But I didn't make a calculation to achieve this number. I entered it to be
an exact value. Now I understand that when a float is used it must be
represented by a fixed number of binary digits. In the things I have read,
this has been cited as the reason for why things get magically rounded. By I
know that binary digits aren't incapable of holding exact numbers. If that
were true, there wouldn't be an accurate computer in the world. So I still
don't understand that if I enter a number to be an exact value of .00000096,
why it can't be stored as 9.60000000e-007?

Thanks,
Marc


"Dennis Lee Bieber" <wlf...@ix.netcom.com> wrote in message
news:st0bk-...@beastie.ix.netcom.com...
> Marc fed this fish to the penguins on Friday 14 March 2003 03:40 pm:


>
> >
> > This appears to be confusing. The variable is set to .00000096 but is
> > passed through as 9.5999999999999991e-007. It appears accurate when
> > printed before the value is returned, is inaccurate when the full
> > return list is printed, accurate when it's printed by itself after the
> > return, and then inaccurate again when the division is made. Why does
> > it do this, and how can I avoid it?
> >

> Because it is a binary floating point value. You run into the
binary
> equivalent of decimal 1/3.
>
> Is 1/3
> = 0.3
> = 0.33
> = 0.3333333
> = 0.333333333333333333333333333333333333333333333333333333
>
> If you multiply back by 3 you get 0.9, 0.99, 0.99999999999...., but you
> do not get 1.0!
>
> How to avoid it? NEVER test a floating point for equality to some
> value. Test for the difference between the two values being LESS than
> some predetermined epsilon.
>
> >>> gap = .00000096
> >>> gap
> 9.5999999999999991e-07
>
> As you can see, it was NOT set .00000096 from the beginning. You
only
> thought it was because str() tries to be nice, and rounds the value to
> something with fewer decimal places.
>
> >>> print "GAP IN ROUTINE " + repr(gap)
> GAP IN ROUTINE 9.5999999999999991e-07


> >>> print "GAP IN ROUTINE " + str(gap)

> GAP IN ROUTINE 9.6e-07
> >>>
>
> --
> > ============================================================== <
> > wlf...@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
> > wulf...@dm.net | Bestiaria Support Staff <
> > ============================================================== <
> > Bestiaria Home Page: http://www.beastie.dm.net/ <
> > Home Page: http://www.dm.net/~wulfraed/ <
>


Grant Edwards

unread,
Mar 15, 2003, 12:55:33 PM3/15/03
to
In article <TrCcnZMtctR...@comcast.com>, Marc wrote:

> But I didn't make a calculation to achieve this number. I entered it to be

> an exact value. [...]


> By I know that binary digits aren't incapable of holding exact numbers.

Wrong. Partly. Some numbers that are exactly representable in base 10 are
not exactly representble in base 2. For example, the number 0.1 (base 10)
can't be exactly represented in base 2. Just like 0.1 (base 3) can't be
exactly represented as a decimal value in base 10: it's 0.33333 (repeats
forever).

> If that were true, there wouldn't be an accurate computer in the world.

There arent. When dealing with floating point, you must assume that
_no_value_is_exact_.

> So I still don't understand that if I enter a number to be an exact value of
> .00000096, why it can't be stored as 9.60000000e-007?

Becausing you entered it in base 10, and it's stored in base 2. Just
because it's an exact value in base 10 it doesn't mean it can be represented
exactly in base 2.

--
Grant Edwards grante Yow! There's enough money
at here to buy 5000 cans of
visi.com Noodle-Roni!

Peter Hansen

unread,
Mar 15, 2003, 1:14:02 PM3/15/03
to

And it might help to envision a base 3 representation, in which
the value 1/3 *could* be represented exactly, but values like 1/2
could not! In fact, here's a case where a different base than 10
can handle values that base 10 cannot handle...

-Peter

Jp Calderone

unread,
Mar 15, 2003, 1:56:08 PM3/15/03
to

I believe the rule is generally expressable - a base can exactly represent
fractions which can be expressed as sums of the inverses of powers of
factors of the base. This makes bases with many relatively prime factors
able to express more fractions exactly. 2 and 3 are poor, because they have
only powers of 1/2 and 1/3 respectively. 4 is just as bad, since it has no
factors that are relatively prime to any factors of 2 (All bases that are
powers of two are equally inexpressive. Bye bye, hexidecimal).

15 is the next best base after 10, and 30 after that. Of course, no base
can exactly represent any fraction, and this doesn't even take into
consideration bases which are, themselves, fractional ;)

Jp

(PS - I worked this all out years ago, and only really remember the part
about the relatively prime factors - if the general expression of the rule
is wrong, I hope it is only because I incorrectly deduced it from the parts
I do remember. Corrections welcome :)

--
1.79 x 10^24 furlongs per picofortnight - It's not just a good idea,
It's the law!
--
up 12 days, 9:59, 9 users, load average: 1.08, 1.02, 0.79

Steven Taschuk

unread,
Mar 15, 2003, 3:39:15 PM3/15/03
to
Quoth Jp Calderone:
[...]

> I believe the rule is generally expressable - a base can exactly represent
> fractions which can be expressed as sums of the inverses of powers of
> factors of the base. [...]

... and only those fractions.

The proof is not difficult. A value x with a terminating
expression
x = 0 . a_1 a_2 a_3 ... a_n
in some base b obviously has the property that
x * b^n is an integer
and conversely, any value x with this property has a terminating
expression. So a fraction p/q has a terminating expression if and
only if q divides some power of b, that is, if and only if all of
q's prime factors are also prime factors of b. Your description
of the rule follows quickly.

[...]


> 15 is the next best base after 10, and 30 after that. Of course, no base
> can exactly represent any fraction, and this doesn't even take into
> consideration bases which are, themselves, fractional ;)

6 and 14 seem just as good as 10 and 15 to me, by this criterion.

--
Steven Taschuk "The world will end if you get this wrong."
stas...@telusplanet.net -- "Typesetting Mathematics -- User's Guide",
Brian Kernighan and Lorrinda Cherry

Erik Max Francis

unread,
Mar 15, 2003, 3:46:48 PM3/15/03
to
Jp Calderone wrote:

> 15 is the next best base after 10, and 30 after that. Of course, no
> base
> can exactly represent any fraction, and this doesn't even take into
> consideration bases which are, themselves, fractional ;)

The traditional "next best" base after 10 will be 12. That's why our
clocks divide time into 12-hour chunks (well, two of them, so it's 24),
etc. Next after that is 60, for equally obvious reasons.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ All bad poetry springs from genuine feeling.
\__/ Oscar Wilde
Bosskey.net: Unreal Tournament 2003 / http://www.bosskey.net/ut2k3/
A personal guide to Unreal Tournament 2003.

Steven Taschuk

unread,
Mar 15, 2003, 4:47:49 PM3/15/03
to
Quoth Grant Edwards:

> In article <TrCcnZMtctR...@comcast.com>, Marc wrote:
[...]

> > So I still don't understand that if I enter a number to be an exact value of
> > .00000096, why it can't be stored as 9.60000000e-007?
>
> Becausing you entered it in base 10, and it's stored in base 2. Just
> because it's an exact value in base 10 it doesn't mean it can be represented
> exactly in base 2.

For concreteness, it may be interesting to note that
x = 9.6e-7
y = 9.5999999999999991e-7
are in binary approximately:
x = 1.000000011011001010110010100110100100011010010010101101100e-20
y = 1.000000011011001010110010100110100100011010010010101011111e-20
These values first differ at the 53rd significant bit, here: ^.

Even if the value in question had a terminating binary expansion
(which it doesn't), it takes a lot of precision to distinguish
these two values. It's *just* within the capacity of IEEE 754
double-precision floats, I think.

--
Steven Taschuk 7\ 7'Z {&~ .
stas...@telusplanet.net Y r --/hG-
(__/ )_ 1^1`

Bengt Richter

unread,
Mar 15, 2003, 9:11:43 PM3/15/03
to
TOn 15 Mar 2003 17:55:33 GMT, Grant Edwards <gra...@visi.com> wrote:

>In article <TrCcnZMtctR...@comcast.com>, Marc wrote:
>
>> But I didn't make a calculation to achieve this number. I entered it to be
>> an exact value. [...]
>> By I know that binary digits aren't incapable of holding exact numbers.
>
>Wrong. Partly. Some numbers that are exactly representable in base 10 are
>not exactly representble in base 2. For example, the number 0.1 (base 10)
>can't be exactly represented in base 2. Just like 0.1 (base 3) can't be
>exactly represented as a decimal value in base 10: it's 0.33333 (repeats
>forever).
>
>> If that were true, there wouldn't be an accurate computer in the world.
>
>There arent. When dealing with floating point, you must assume that
>_no_value_is_exact_.

Please qualify such statements, so you don't encourage superstitions ;-)

As I'm sure you know, all legal (w.r.t. some standard like IEEE 754)
floating point numbers are represented as specific bit patterns, and
those patterns correspond EXACTLY to specific EXACT real numbers.

It may be that no bit pattern is available to represent the exact
number one wants to represent in floating point, but that doesn't
mean that the nearest available numbers aren't exact in themselves.

>
>> So I still don't understand that if I enter a number to be an exact value of
>> .00000096, why it can't be stored as 9.60000000e-007?

Actually, it can, but that is not what happens if you store it as a floating double.


>
>Becausing you entered it in base 10, and it's stored in base 2. Just
>because it's an exact value in base 10 it doesn't mean it can be represented
>exactly in base 2.
>

Right. It never ends ;-) Sigh.

Regards,
Bengt Richter

Marc

unread,
Mar 16, 2003, 1:52:09 AM3/16/03
to
The penguins, it appears, have been well fed today. I now see the error in
my thinking and have issued a slight "NEWMAN" under my breath as I slowly
regain knowledge from a college semester long since passed. Not to mention
physics classes which spent quite a bit of time discussing the difference
between accuracy and precision...

Thanks for all the info.


Dan Bishop

unread,
Mar 16, 2003, 3:58:02 AM3/16/03
to
Steven Taschuk <stas...@telusplanet.net> wrote in message news:<mailman.1047761005...@python.org>...

Normalized IEEE double has 53 bits of precision (including the
implicit leading 1), so you would be right if it weren't for the fact
that both values get rounded to
1.0000000110110010101100101001101001000110100100101011e-20.

Dan Bishop

unread,
Mar 16, 2003, 4:38:40 AM3/16/03
to
Steven Taschuk <stas...@telusplanet.net> wrote in message news:<mailman.1047756866...@python.org>...

> Quoth Jp Calderone:
> [...]
> > I believe the rule is generally expressable - a base can exactly represent
> > fractions which can be expressed as sums of the inverses of powers of
> > factors of the base. [...]
>
> ... and only those fractions.
>
> The proof is not difficult. A value x with a terminating
> expression
> x = 0 . a_1 a_2 a_3 ... a_n
> in some base b obviously has the property that
> x * b^n is an integer
> and conversely, any value x with this property has a terminating
> expression. So a fraction p/q has a terminating expression if and
> only if q divides some power of b, that is, if and only if all of
> q's prime factors are also prime factors of b. Your description
> of the rule follows quickly.
>
> [...]
> > 15 is the next best base after 10, and 30 after that. Of course, no base
> > can exactly represent any fraction, and this doesn't even take into
> > consideration bases which are, themselves, fractional ;)
>
> 6 and 14 seem just as good as 10 and 15 to me, by this criterion.

Imho, 6 would be better than either 10 or 14, because for any
sufficiently large finite range of integers, there are more multiples
of 3 than multiples of 5 and 7.

If we define the utility of a number base as proportional to the
number of its factors (excluding itself), and inversely proportional
to the magnitude of those factors (and use the Python script at the
end of this message to calculate those factors), we find that the best
bases are 12 (1.562), 6 (1.500), and 24 (1.361), and that bases 14,
21, 22, 25-28, and 32-35 are worse than the prime bases.

------------------------------------------------------------------------

#!/usr/bin/env python

from __future__ import division
import operator

def factors(n):
# list of factors of n, including 1 and excluding n
return [i for i in xrange(1, n // 2 + 1) if not n % i]

def mean(seq):
return reduce(operator.add, seq) / len(seq)

def utility(base):
# an arbitrary definition of how "good" a number base is
f = factors(base)
return len(f) / mean(f)

def main():
print 'base utility'
print '---- -------'
for base in xrange(2, 37):
print ' %2d %.3f' % (base, utility(base))

if __name__ == '__main__':
main()

Steven Taschuk

unread,
Mar 16, 2003, 3:47:54 PM3/16/03
to
Quoth Dan Bishop:

> Steven Taschuk <stas...@telusplanet.net> wrote in message news:<mailman.1047761005...@python.org>...
[...]

> > x = 1.000000011011001010110010100110100100011010010010101101100e-20
> > y = 1.000000011011001010110010100110100100011010010010101011111e-20
> > These values first differ at the 53rd significant bit, here: ^.
> > [Distinguishing these is] *just* within the capacity of IEEE 754

> > double-precision floats, I think.
>
> Normalized IEEE double has 53 bits of precision (including the
> implicit leading 1), so you would be right if it weren't for the fact
> that both values get rounded to
> 1.0000000110110010101100101001101001000110100100101011e-20.

Ah, yes, of course. So, we'd need 54 bits, as it happens.

Thanks for the correction.

--
Steven Taschuk stas...@telusplanet.net
"Its force is immeasurable. Even Computer cannot determine it."
-- _Space: 1999_ episode "Black Sun"

Steven Taschuk

unread,
Mar 16, 2003, 3:56:07 PM3/16/03
to
Quoth Dan Bishop:

> Steven Taschuk <stas...@telusplanet.net> wrote in message news:<mailman.1047756866...@python.org>...
[...]

> > 6 and 14 seem just as good as 10 and 15 to me, by this criterion.
>
> Imho, 6 would be better than either 10 or 14, because for any
> sufficiently large finite range of integers, there are more multiples
> of 3 than multiples of 5 and 7.
>
> If we define the utility of a number base as proportional to the
> number of its factors (excluding itself), and inversely proportional
> to the magnitude of those factors (and use the Python script at the
> end of this message to calculate those factors), we find that the best
> bases are 12 (1.562), 6 (1.500), and 24 (1.361), and that bases 14,
> 21, 22, 25-28, and 32-35 are worse than the prime bases.

The thing is that we are not concerned with all factors, only the
prime ones. For example, the fractions exactly representable in
base 12 are the same as those exactly representable in base 6;
that 4 divides 12 gains us nothing. (I assume that the length of
the terminating expression is not of interest; only *that* it
terminates is.)

--
Steven Taschuk o- @
stas...@telusplanet.net 7O )
" (

John Machin

unread,
Mar 16, 2003, 4:28:30 PM3/16/03
to
dan...@yahoo.com (Dan Bishop) wrote in message news:<ad052e5c.03031...@posting.google.com>...

>
> If we define the utility of a number base as proportional to the
> number of its factors (excluding itself), and inversely proportional
> to the magnitude of those factors (and use the Python script at the
> end of this message to calculate those factors), we find that the best
> bases are 12 (1.562), 6 (1.500), and 24 (1.361), and that bases 14,
> 21, 22, 25-28, and 32-35 are worse than the prime bases.
>
>
> def factors(n):
> # list of factors of n, including 1 and excluding n
> return [i for i in xrange(1, n // 2 + 1) if not n % i]
>

Wouldn't it be better to exclude non-prime factors of the base?

xtian

unread,
Mar 16, 2003, 10:40:12 PM3/16/03
to
dan...@yahoo.com (Dan Bishop) wrote in message news:<ad052e5c.03031...@posting.google.com>...
> Imho, 6 would be better than either 10 or 14, because for any
> sufficiently large finite range of integers, there are more multiples
> of 3 than multiples of 5 and 7.
>
> If we define the utility of a number base as proportional to the
> number of its factors (excluding itself), and inversely proportional
> to the magnitude of those factors (and use the Python script at the
> end of this message to calculate those factors), we find that the best
> bases are 12 (1.562), 6 (1.500), and 24 (1.361), and that bases 14,
> 21, 22, 25-28, and 32-35 are worse than the prime bases.
>

OT (although arguably no more than the other stuff immediately before
in the thread ;)- I found this discussion of the benefits of number
systems based on what the author terms versatile numbers very
interesting:
http://www.earth360.com/math-versatile.html

cheers,
xtian

marshall

unread,
Mar 16, 2003, 11:08:00 PM3/16/03
to
Erik Max Francis <m...@alcyone.com> wrote in message news:<3E739138...@alcyone.com>...

> Jp Calderone wrote:
>
> > 15 is the next best base after 10, and 30 after that. Of course, no
> > base
> > can exactly represent any fraction, and this doesn't even take into
> > consideration bases which are, themselves, fractional ;)
>
> The traditional "next best" base after 10 will be 12. That's why our
> clocks divide time into 12-hour chunks (well, two of them, so it's 24),
> etc. Next after that is 60, for equally obvious reasons.

Actually the division of day and night into 12 hours dates back to the
Babylonians who had a base 60 system. 12 was probably chosen as a
factor of 60 and 12 was special becuase of the division of the year
into roughly 12 lunar months and the demarcation of the night by
twelve constellations.

Marshall

0 new messages