473,383 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Simple addition

Hi,

I tried a simple addition with python and I don't understand what is
going on:

$python
464.73+279.78

744.50999999999999

weird isn't it ? I use python2.3.

comments welcome
Mathieu
Jul 18 '05 #1
11 1651
Mathieu Malaterre wrote:
$python
>>464.73+279.78 744.50999999999999

weird isn't it ? I use python2.3.


Mathieu, you can find a full explanation of what you're seeing at the
following documentation link:
http://www.python.org/doc/current/tut/node15.html

From that page:

"Note that this is in the very nature of binary floating-point: this is
not a bug in Python, it is not a bug in your code either, and you'll see
the same kind of thing in all languages that support your hardware's
floating-point arithmetic (although some languages may not display the
difference by default, or in all output modes).

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:

print str(0.1)

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."
Jul 18 '05 #2
Brian wrote:
Mathieu Malaterre wrote:
$python
>>464.73+279.78

744.50999999999999

weird isn't it ? I use python2.3.

Mathieu, you can find a full explanation of what you're seeing at the
following documentation link:
http://www.python.org/doc/current/tut/node15.html


Thanks a bunch Brian !
Jul 18 '05 #3
>>>>> Brian <py*****************************@invalid.net> (B) wrote:
print str(0.1)

B> 0.1

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

On the other hand, python could have done better. There are algorithms to
print floating point numbers properly with a more pleasant output[1]:
in this particular case python could have given "0.1" also with "print 0.1".
Unfortunately most C libraries only use the stupid algorithm which often
gives some useless digits.

This is because ideally it should print the representation with the least
number of digits that when read back gives the same internal value as the
number printed. In this case that is obviously "0.1".

[1] Guy L. Steele, Jr. Jon L. White, How to print floating-point numbers
accurately, Proceedings of the ACM SIGPLAN 1990 conference on Programming
language design and implementation, Pages: 112 - 126.
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.***********@hccnet.nl
Jul 18 '05 #4

"Piet van Oostrum" <pi**@cs.uu.nl> wrote in message
news:wz************@cs.uu.nl...
>> Brian <py*****************************@invalid.net> (B) wrote: print str(0.1) B> 0.1

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

On the other hand, python could have done better.
Python gives you a choice between most exact and 'pleasant'. This *is*
better, in my opinion, than no choice.
There are algorithms to
print floating point numbers properly with a more pleasant output[1]:
in this particular case python could have given "0.1" also with "print 0.1".

What? In 2.2:
print 0.1

0.1

did this change in 2.3?
Unfortunately most C libraries only use the stupid algorithm which often
gives some useless digits.
They are not useless if you want more accuracy about what you have and what
you will get with further computation. Tracking error expansion is an
important part of designing floating point calculations.
This is because ideally it should print the representation with the least
number of digits that when read back gives the same internal value as the
number printed. In this case that is obviously "0.1".


This is opinion, not fact. Opinions are divided.

Terry J. Reedy
Jul 18 '05 #5
Mathieu Malaterre <mm******@nycap.rr.com> wrote in message news:<LW*******************@twister.nyroc.rr.com>. ..
Hi,

I tried a simple addition with python and I don't understand what is
going on:

$python
>>464.73+279.78

744.50999999999999


You computer does arithmetic in binary. None of these numbers can be
exactly represented as a binary fraction.

464.73 = bin 111010000.10 11101011100001010001 11101011100001010001...
279.78 = bin 100010111.1 10001111010111000010 10001111010111000010...

They get rounded to the nearest 53-bit float:

464.73 ~= 0x1.D0BAE147AE147p+8
279.78 ~= 0x1.17C7AE147AE14p+8
--------------------
0x2.E8828F5C28F5Bp+8
~= 0x1.744147AE147AEp+9 after normalization

The exact decimal equivalent of this sum is
744.509999999999990905052982270717620849609375. Python's repr()
rounds this to 17 decimal digits, or "744.50999999999999".
Jul 18 '05 #6
>>>>> "Terry Reedy" <tj*****@udel.edu> (TR) wrote:

TR> "Piet van Oostrum" <pi**@cs.uu.nl> wrote in message
TR> news:wz************@cs.uu.nl...
>>>>> Brian <py*****************************@invalid.net> (B) wrote:

>>>> print str(0.1) B> 0.1
B> It's important to realize that this is, in a real sense, an illusion:
TR> the
B> value in the machine is not exactly 1/10, you're simply rounding the
B> display of the true machine value."
On the other hand, python could have done better.
TR> Python gives you a choice between most exact and 'pleasant'. This *is*
TR> better, in my opinion, than no choice.

0.10000000000000001 is not more exact then 0.1. It is a false illusion of
exactness.
There are algorithms to
print floating point numbers properly with a more pleasant output[1]:
in this particular case python could have given "0.1" also with "print TR> 0.1".

TR> What? In 2.2: print 0.1

TR> 0.1

TR> did this change in 2.3?

Ok, mistake, I should have left out the print. But you should know what I
mean.
Unfortunately most C libraries only use the stupid algorithm which often
gives some useless digits.
TR> They are not useless if you want more accuracy about what you have and what
TR> you will get with further computation. Tracking error expansion is an
TR> important part of designing floating point calculations.
This is because ideally it should print the representation with the least
number of digits that when read back gives the same internal value as the
number printed. In this case that is obviously "0.1".


TR> This is opinion, not fact. Opinions are divided.

It would cause no errors and it would prevent a lot of the questions that
appear about every few days here about this subject. So what is the
advantage of printing 0.10000000000000001 or xx.xxx999999999998?
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.***********@hccnet.nl
Jul 18 '05 #7
"Terry Reedy" <tj*****@udel.edu> wrote in message news:<3O********************@comcast.com>...
"Piet van Oostrum" <pi**@cs.uu.nl> wrote in message
news:wz************@cs.uu.nl...
>>>> Brian <py*****************************@invalid.net> (B) wrote: [repr(0.1) is ugly!]

Unfortunately most C libraries only use the stupid algorithm which often
gives some useless digits.


They are not useless if you want more accuracy about what you have


Why not display the *exact* decimal representation,
"0.10000000000000000555111512312578270211815834045 41015625"?
and what you will get with further computation.
Tracking error expansion is an
important part of designing floating point calculations.


We're talking about human-readable representation, not calculations.
Jul 18 '05 #8
Dan Bishop wrote:
Why not display the *exact* decimal representation,
"0.10000000000000000555111512312578270211815834045 41015625"?


This has my vote. Unfortunately Python seems incapable of figuring out all
of those digits.

Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
'%.64f' % 0.1

'0.10000000000000001000000000000000000000000000000 00000000000000000'
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #9
> > > Unfortunately most C libraries only use the stupid algorithm which
often
gives some useless digits.


They are not useless if you want more accuracy about what you have


Why not display the *exact* decimal representation,
"0.10000000000000000555111512312578270211815834045 41015625"?


One can do better than that--or at least something I think is better.

Many moons ago, Guy Steele proposed an elegant pair of rules for converting
between decimal and internal floating-point, be it binary, decimal,
hexadecimal, or something else entirely:

1) Input (i.e. conversion from decimal to internal form) always yields
the closest (rounded) internal value to the given input.

2) Output (i.e. conversion from internal form to decimal) yields the
smallest number of significant digits that, when converted back to internal
form, yields exactly the same value.

This scheme is useful because, among other things, it ensures that all
numbers with only a few significant digits will convert to internal form and
back to decimal without change. For example, consider 0.1. Converting 0.1
to internal form yields the closest internal number to 0.1. Call that
number X. Then when we write X back out again, we *must* get 0.1, because
0.1 is surely the decimal number with the fewest significant digits that
yields X when converted.

I have suggested in the past that Python use these conversion rules. It
turns out that there are three strong arguments against it:

1) It would preclude using the native C library for conversions, and
would probably yield different results from C under some circumstances.

2) It is difficult to implement portably, and if it is not implemented
portably, it must be reimplemented for every platform.

3) It potentially requires unbounded-precision arithmetic to do the
conversions, although a clever implementation can avoid it most of the time.

I still think it would be a good idea, but I can see that it would be more
work than is feasible. I don't want to do the work myself, anyway :-)
Jul 18 '05 #10
Rainer Deyke wrote:
Dan Bishop wrote:
Why not display the *exact* decimal representation,
"0.100000000000000005551115123125782702118158340 4541015625"?

This has my vote. Unfortunately Python seems incapable of figuring out all
of those digits.

Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
'%.64f' % 0.1
'0.10000000000000001000000000000000000000000000000 00000000000000000'


Python 2.3.3 seems to be able to do it on Red Hat Linux 9.0:

[rodh@rodh rodh]$ python
Python 2.3.3 (#1, Dec 20 2003, 17:47:13)
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
'%.64f' % 0.1 '0.10000000000000000555111512312578270211815834045 41015625000000000'

Must be a M$ MSC problem.

--
Rod
Jul 18 '05 #11
>>>>> "Andrew Koenig" <ar*@acm.org> (AK) wrote:

AK> Many moons ago, Guy Steele proposed an elegant pair of rules for converting
AK> between decimal and internal floating-point, be it binary, decimal,
AK> hexadecimal, or something else entirely:

That was exactly what I was suggesting. I even included the bib reference.
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.***********@hccnet.nl
Jul 18 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Gavin Bauer | last post by:
My DOS window (running in windows ME) closes the second it finishes running my programs. As you can imagine, this makes it hard to see the results. I've gotten in the habit of putting...
19
by: Dales | last post by:
I have a custom control that builds what we refer to as "Formlets" around some content in a page. These are basically content "wrapper" sections that are tables that have a colored header and...
8
by: rdavis7408 | last post by:
I am attempting what I would think would be a simple calculation of the cost of traveling a single mile. But I can not figure this out. The following is my script. Any help would be appreciated. ...
4
by: Ranginald | last post by:
Sorry for the simple question but thanks in advance: My goal is to create reusale code for a web app in C#. I have written the code already as a windows app but here is where I am confused: ...
13
by: aum | last post by:
Hi, I'm a Python programmer, just starting to get into javascript. On reading some of the js guides, and not liking any of the OO usage patterns I saw, I've cooked up something which python...
5
by: Mike | last post by:
Hello All, Please, if anyone can point me to the problem, I'd sure appreciate it! I am very new to VB programming and not a programmer to begin with. This is part of a Visual Basic 2005 Express...
1
by: Synapse | last post by:
Hello... We were asked to create a simple calculator program in our C++ subject by using loops only. i have a problem in creating a loop in the multiplication and division operation so please can...
5
by: wazzup | last post by:
My task is Create a program to read a simple integer expression and display the result. "Simple" means no parentheses are allowed and only the +, -, *, and / operators are allowed. I think...
2
by: aagase29 | last post by:
The code below accepts two numbers from textboxes and should show the addition in the third one.I can t figure out how to display addition in the third text box... <html> <body> <form...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.