float / rounding question

H

helen.m.flynn

Hi I'm very much a beginner with Python.
I want to write a function to convert celcius to fahrenheit like this
one:

def celciusToFahrenheit(tc):
tf = (9/5)*tc+32
return tf

I want the answer correct to one decimal place, so
celciusToFahrenheit(12) would return 53.6.

Of course the function above returns 53.600000000000001.

How do I format it correctly?
 
S

sabatier

Hi I'm very much a beginner with Python.
I want to write a function to convert celcius to fahrenheit like this
one:

def celciusToFahrenheit(tc):
tf = (9/5)*tc+32
return tf

I want the answer correct to one decimal place, so
celciusToFahrenheit(12) would return 53.6.

Of course the function above returns 53.600000000000001.

How do I format it correctly?

By the way, I tried this:

return '%2.1f' % tf but that returns a string instead of a number.

Any other suggestions?
 
J

Jorge Godoy

sabatier said:
By the way, I tried this:

return '%2.1f' % tf but that returns a string instead of a number.

Any other suggestions?

But you are asking for a string on your format string above.

And also formatting make no sense in other context since a number is a
number and 53.600000 and 53.6 are the same number (besides precision).

You are concerned with how numbers are represented in binary. When
displaying the value use the format string you shown above and all will
work.
 
N

Necmettin Begiter

25 February 2008 Monday 12:44:46 tarihinde (e-mail address removed) şunları yazmıştı:
Hi I'm very much a beginner with Python.
I want to write a function to convert celcius to fahrenheit like this
one:

def celciusToFahrenheit(tc):
tf = (9/5)*tc+32
return tf

I want the answer correct to one decimal place, so
celciusToFahrenheit(12) would return 53.6.

Of course the function above returns 53.600000000000001.

How do I format it correctly?

Use the round(number,digits) function:

tf = round((9/5)*tc+32,1)
 
C

casevh

Hi I'm very much a beginner with Python.
I want to write a function to convert celcius to fahrenheit like this
one:

def celciusToFahrenheit(tc):
tf = (9/5)*tc+32
return tf

I want the answer correct to one decimal place, so
celciusToFahrenheit(12) would return 53.6.

Of course the function above returns 53.600000000000001.

How do I format it correctly?

That is the normal behavior for binary (radix-2) numbers. Just like it
is impossible write 1/3 exactly as a decimal (radix-10) number, 536/10
cannot be written exactly as a binary number. If you really need
decimal numbers, use the Decimal class.

See http://docs.python.org/tut/node16.html.

casevh
 
S

Sion Arrowsmith

Necmettin Begiter said:
25 February 2008 Monday 12:44:46 tarihinde (e-mail address removed) =C5=9Fun=
lar=C4=B1 yazm=C4=B1=C5=9Ft=C4=B1:

Use the round(number,digits) function:

tf =3D round((9/5)*tc+32,1)
53.600000000000001
 
M

Mel

Hi I'm very much a beginner with Python.
I want to write a function to convert celcius to fahrenheit like this
one:

def celciusToFahrenheit(tc):
tf = (9/5)*tc+32
return tf

I want the answer correct to one decimal place, so
celciusToFahrenheit(12) would return 53.6.

Of course the function above returns 53.600000000000001.

How do I format it correctly?

print celcisuToFahrenheit (12)

will do fine.


Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information..... tf = (float(9)/5)*tc+32
.... return tf
....53.6


The straight value display from the interpreter pursues precision to
the bitter end, doing its formatting with the repr function. print
uses str formatting for a more expected result.

Mel.
 
T

Terry Reedy

| Hi I'm very much a beginner with Python.
| I want to write a function to convert celcius to fahrenheit like this
| one:
|
| def celciusToFahrenheit(tc):
| tf = (9/5)*tc+32
| return tf

Unless you are importing 'integer division' or using 3.0, that should be
9.0/5.0.

| I want the answer correct to one decimal place, so
| celciusToFahrenheit(12) would return 53.6.

As written, running above on 2.x returns 44.

tjr
 
J

John Machin

| Hi I'm very much a beginner with Python.
| I want to write a function to convert celcius to fahrenheit like this
| one:
|
| def celciusToFahrenheit(tc):
| tf = (9/5)*tc+32
| return tf

Unless you are importing 'integer division' or using 3.0, that should be
9.0/5.0.

Has the syntax changed? I thought it was:
from __future__ import division

The OP may wish to avoid the confusion and the pointless division by
using:
tf = 1.8 * tc + 32
 
P

Piet van Oostrum

C> That is the normal behavior for binary (radix-2) numbers. Just like it
C> is impossible write 1/3 exactly as a decimal (radix-10) number, 536/10
C> cannot be written exactly as a binary number. If you really need
C> decimal numbers, use the Decimal class.

Sorry to come in so late in this discussion. Although it is correct to say
that many real numbers that have an exact decimal representation cannot be
exactly represented in binary, that is no excuse to print 53.6 as
53.600000000000001. This is just lousy printing and the fact that this kind
of question comes up every week shows that it is confusing to many people.

Python just uses the C library for printing, I presume, and the conversion
routines in the C library are rather simplistic. It is, however, possible
to do better, so that 53.6 -- although internally represented as something
that could be described as 53.600000000000001 -- will actually be printed
as 53.6. Indeed, when reading back the printed value you get the exact
representation as the internal number that was printed, and IMHO, that is
what matters. Apparently there is more than one representation that has
this property. I would guess (but didn't check) that
53.60000000000000100000001 also gives the same number. From all these
representations it would be best to choose the simplest one, i.e. 53.6.
This problem and a solution has been described in one of the classical
computer science publications:

http://portal.acm.org/citation.cfm?id=93559
 
M

Mark Dickinson

Python just uses the C library for printing, I presume, and the conversion
routines in the C library are rather simplistic. It is, however, possible
to do better, so that 53.6 -- although internally represented as something
that could be described as 53.600000000000001 -- will actually be printed
as 53.6.

There are issues with doing this portably and reliably. See

http://bugs.python.org/issue1580

for a recent discussion.

Mark
 
S

Steven D'Aprano

Sorry to come in so late in this discussion. Although it is correct to
say that many real numbers that have an exact decimal representation
cannot be exactly represented in binary, that is no excuse to print 53.6
as 53.600000000000001. This is just lousy printing and the fact that
this kind of question comes up every week shows that it is confusing to
many people.

Good. That's a feature, not a bug.

Floats *are* confusing and unintuitive. Anyone with pretensions to be a
programmer should get over the illusion that floats are reals as soon as
possible, before they learn bad habits that have to be unlearned. If that
starts with them asking why they get 53.600000000000001 instead of 53.6,
so be it. If they want to be insulated from the harsh reality, they can
do this:
53.6
 
D

Dennis Lee Bieber

Sorry to come in so late in this discussion. Although it is correct to say
that many real numbers that have an exact decimal representation cannot be
exactly represented in binary, that is no excuse to print 53.6 as
53.600000000000001. This is just lousy printing and the fact that this kind
of question comes up every week shows that it is confusing to many people.

Looks like "print" already does what you expect.

And, of course, one may use detailed formatting for output...
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
M

Mark Dickinson

Good. That's a feature, not a bug.

Even so, it's not clear that Python's current behaviour couldn't be
improved. I have a mild dislike of the lack of consistency in the
following, which arises from Python arbitrarily stripping trailing
zeros from the result returned by the C library functions:
10.4

Piet van Oostrum's suggestion gives one nice way of dealing with
this inconsistency. Unfortunately it doesn't look easy to
implement this in practice: the main difficulty seems to be
that to ensure float(repr(x))==x round-tripping you'd
need to write routines to take control of both str -> float and
float -> str conversions, not forgetting that those routines
have to be reasonably fast, and work correctly on various
non IEEE 754 platforms as well as the usual ones. This means
adding, maintaining and testing hundreds of lines of
complicated code, where right now a few C library calls suffice.

Mark
 
M

Mark Dickinson

following, which arises from Python arbitrarily stripping trailing
zeros from the result returned by the C library functions:

Correction: on closer examination it's not Python doing the
stripping of trailing zeros; it's the C library.

Mark
 
R

Roel Schroeven

Mark Dickinson schreef:
Even so, it's not clear that Python's current behaviour couldn't be
improved. I have a mild dislike of the lack of consistency in the
following, which arises from Python arbitrarily stripping trailing
zeros from the result returned by the C library functions:

10.4

Actually I don't see what all the fuss is about. If you want a nicely
rounded number, use print or str() or the % operator.

*Only* when you use repr() or when the interactive interpreter uses it
to print the value of the expression, you get something that doesn't
look as nice.

--
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
-- Isaac Asimov

Roel Schroeven
 
P

Piet van Oostrum

Dennis Lee Bieber said:
DLB> On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum <[email protected]>
DLB> declaimed the following in comp.lang.python:
DLB> Looks like "print" already does what you expect.

No, what you see is not the behaviour of `print' but of `str'. `print' uses
`str' to do the formatting instead of `repr' whereas the interactive prompt
uses `str'. `str' is meant to please the human reader, and `repr' is
supposed to give you something that you can use as input and get exactly
the same value. But `str' does it by just giving you less accuracy, thus
sweeping the problem under the carpet:
53.6

False

'53.599999999989997'

True

'53.600000000000001'
True
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top