# float / rounding question

Discussion in 'Python' started by helen.m.flynn@gmail.com, Feb 25, 2008.

1. ### Guest

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?

, Feb 25, 2008

2. ### sabatierGuest

On Feb 25, 10:44 am, wrote:
> 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?

sabatier, Feb 25, 2008

3. ### Jorge GodoyGuest

sabatier wrote:

> On Feb 25, 10:44 am, wrote:
>> 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?

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.

Jorge Godoy, Feb 25, 2008
4. ### Necmettin BegiterGuest

25 February 2008 Monday 12:44:46 tarihinde ÅŸ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)

Necmettin Begiter, Feb 25, 2008
5. ### casevhGuest

On Feb 25, 2:44 am, wrote:
> 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

casevh, Feb 25, 2008
6. ### Sion ArrowsmithGuest

Necmettin Begiter <> wrote:
>25 February 2008 Monday 12:44:46 tarihinde =C5=9Fun=
>lar=C4=B1 yazm=C4=B1=C5=9Ft=C4=B1:
>> Of course the function above returns 53.600000000000001.
>>=20
>> How do I format it correctly?

>
>Use the round(number,digits) function:
>
>tf =3D round((9/5)*tc+32,1)

>>> 53.6

53.600000000000001
>>> round(53.6, 1)

53.600000000000001

--
\S -- -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

Sion Arrowsmith, Feb 25, 2008
7. ### MelGuest

wrote:
> 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
>>> def celciusToFahrenheit(tc):

.... tf = (float(9)/5)*tc+32
.... return tf
....
>>> celciusToFahrenheit (12)

53.600000000000001
>>> print celciusToFahrenheit (12)

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.

Mel, Feb 25, 2008
8. ### Terry ReedyGuest

<> wrote in message
news:...
| 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

Terry Reedy, Feb 25, 2008
9. ### John MachinGuest

On Feb 26, 7:14 am, "Terry Reedy" <> wrote:
> <> wrote in message
>
> news:...
> | 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

>
> | 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

John Machin, Feb 25, 2008
10. ### Piet van OostrumGuest

>>>>> casevh <> (C) wrote:

>C> On Feb 25, 2:44 am, wrote:
>>> 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?

>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
--
Piet van Oostrum <>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email:

Piet van Oostrum, Mar 7, 2008
11. ### Mark DickinsonGuest

On Mar 7, 5:12 pm, Piet van Oostrum <> wrote:
> 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

Mark Dickinson, Mar 8, 2008
12. ### Steven D'ApranoGuest

On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum wrote:

> 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
so be it. If they want to be insulated from the harsh reality, they can
do this:

>>> print 53.6

53.6

--
Steven

Steven D'Aprano, Mar 8, 2008
13. ### Dennis Lee BieberGuest

On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum <>
declaimed the following in comp.lang.python:

> 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.
>
>>> 53.6

53.600000000000001
>>> print 53.6

53.6
>>> print str(53.6)

53.6
>>> print repr(53.6)

53.600000000000001
>>>

Looks like "print" already does what you expect.

>>> a = 53.6
>>> a

53.600000000000001
>>> "%5.1f" % a

' 53.6'
>>>

And, of course, one may use detailed formatting for output...
--
Wulfraed Dennis Lee Bieber KD6MOG

HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: )
HTTP://www.bestiaria.com/

Dennis Lee Bieber, Mar 8, 2008
14. ### Mark DickinsonGuest

On Mar 7, 11:23 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum wrote:
> > 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.

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.1

10.1
>>> 10.2

10.199999999999999
>>> 10.3

10.300000000000001
>>> 10.4

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

Mark Dickinson, Mar 8, 2008
15. ### Mark DickinsonGuest

On Mar 8, 11:34 am, Mark Dickinson <> wrote:
> 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

Mark Dickinson, Mar 8, 2008
16. ### Roel SchroevenGuest

Mark Dickinson schreef:
> On Mar 7, 11:23 pm, Steven D'Aprano <st...@REMOVE-THIS-
> cybersource.com.au> wrote:
>> On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum wrote:
>>> 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.

>
> 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.1

> 10.1
>>>> 10.2

> 10.199999999999999
>>>> 10.3

> 10.300000000000001
>>>> 10.4

> 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

Roel Schroeven, Mar 8, 2008
17. ### Piet van OostrumGuest

>>>>> Dennis Lee Bieber <> (DLB) wrote:

>DLB> On Fri, 07 Mar 2008 23:12:27 +0100, Piet van Oostrum <>
>DLB> declaimed the following in comp.lang.python:

>>> 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.
>>>
>>>>> 53.6

>DLB> 53.600000000000001
>>>>> print 53.6

>DLB> 53.6
>>>>> print str(53.6)

>DLB> 53.6
>>>>> print repr(53.6)

>DLB> 53.600000000000001
>>>>>

>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:

>>> str(53.59999999999)

53.6

>>> 53.59999999999==53.6

False

>>> repr(53.59999999999)

'53.599999999989997'

>>> 53.599999999989997==53.59999999999

True

>>> repr(53.6)

'53.600000000000001'

>>> 53.600000000000001==53.6

True

--
Piet van Oostrum <>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email:

Piet van Oostrum, Mar 10, 2008