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

  2. sabatier Guest

    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
    #2
    1. Advertising

  3. Jorge Godoy Guest

    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
    #3
  4. 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
    #4
  5. casevh Guest

    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
    #5
  6. 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
    #6
  7. Mel Guest

    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
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 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
    #7
  8. Terry Reedy Guest

    <> 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
    #8
  9. John Machin Guest

    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
    #9
  10. >>>>> 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
    #10
  11. 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
    #11
  12. 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
    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:

    >>> print 53.6

    53.6



    --
    Steven
     
    Steven D'Aprano, Mar 8, 2008
    #12
  13. 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
    #13
  14. 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
    #14
  15. 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
    #15
  16. 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
    #16
  17. >>>>> 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
    #17
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Shea Martin
    Replies:
    7
    Views:
    3,600
    P.J. Plauger
    Oct 30, 2003
  2. bd
    Replies:
    0
    Views:
    663
  3. Replies:
    13
    Views:
    858
    Dik T. Winter
    May 15, 2006
  4. Shirsoft
    Replies:
    13
    Views:
    636
    Jerry Coffin
    Feb 10, 2007
  5. Carsten Fuchs
    Replies:
    45
    Views:
    1,648
    James Kanze
    Oct 8, 2009
Loading...

Share This Page