How to truncate/round-off decimal numbers?

Discussion in 'Python' started by Girish Sahani, Jun 20, 2006.

  1. Hi,

    I want to truncate every number to 2 digits after the decimal point. I
    tried the following but it doesnt work.

    >>> a = 2
    >>> b = 3
    >>> round(a*1.0 / b,2)

    0.67000000000000004

    Inspite of specifying 2 in 2nd attribute of round, it outputs all the
    digits after decimal.
    Girish Sahani, Jun 20, 2006
    #1
    1. Advertising

  2. Girish Sahani enlightened us with:
    > I want to truncate every number to 2 digits after the decimal point. I
    > tried the following but it doesnt work.


    Yes it does, read the documentation about floating points.

    >>>> a = 2
    >>>> b = 3
    >>>> round(a*1.0 / b,2)

    > 0.67000000000000004


    If you want to format it, use '%.2f' % (float(a)/b)

    Sybren
    --
    The problem with the world is stupidity. Not saying there should be a
    capital punishment for stupidity, but why don't we just take the
    safety labels off of everything and let the problem solve itself?
    Frank Zappa
    Sybren Stuvel, Jun 20, 2006
    #2
    1. Advertising

  3. Girish Sahani

    MTD Guest

    > >>> a = 2
    > >>> b = 3
    > >>> round(a*1.0 / b,2)

    > 0.67000000000000004
    >
    > Inspite of specifying 2 in 2nd attribute of round, it outputs all the
    > digits after decimal.


    This is because of floating point inaccuracy. The system cannot
    accurately represent some integers, however it does its best to
    approximate them. Notice this:

    >>> x = 2.0/3
    >>> x

    0.66666666666666663
    >>> round(x,2)

    0.67000000000000004
    >>> s = str(round(x,2))
    >>> s

    '0.67'
    MTD, Jun 20, 2006
    #3
  4. Girish Sahani

    MTD Guest

    > The system cannot
    > accurately represent some integers,


    Er, I meant FLOATS. Doh.

    Anyway, just to underline the example:

    >>> x

    0.66666666666666663
    >>> s = str(round(x,2))
    >>> s

    '0.67'
    >>> f = float(s)
    >>> f

    0.67000000000000004
    >>> f == round(x,2)

    True
    MTD, Jun 20, 2006
    #4
  5. Girish Sahani a écrit :
    > Hi,
    >
    > I want to truncate every number to 2 digits after the decimal point. I
    > tried the following but it doesnt work.
    >
    >>>> a = 2
    >>>> b = 3
    >>>> round(a*1.0 / b,2)

    > 0.67000000000000004
    >
    > Inspite of specifying 2 in 2nd attribute of round, it outputs all the
    > digits after decimal.


    There are two operations:

    1) calculate of round(), which return a float number result, with the
    well known problem of floating point numbers represantation (see the FAQ).

    2) print that number, where default printing of last expression result
    in the cli interpreter displays up to the highest precision, print
    statement works differently:

    >>> a=2
    >>> b=3
    >>> c=round(a*1.0/b,2)
    >>> c

    0.67000000000000004
    >>> print c

    0.67
    >>>


    A+

    Laurent.
    Laurent Pointal, Jun 20, 2006
    #5
  6. Sybren Stuvel wrote:
    > Girish Sahani enlightened us with:
    >> I want to truncate every number to 2 digits after the decimal point....
    >>>>> a = 2
    >>>>> b = 3
    >>>>> round(a*1.0 / b,2)

    >> 0.67000000000000004

    >
    > If you want to format it, use '%.2f' % (float(a)/b)


    Sybren has this right. If you follow everyone else's advice,
    you'll eventually discover:

    >>> print round(11024. / 5000.1, 2)

    only gives you "2.2", not "2.20" (which is what, I suspect, you want).

    --Scott David Daniels
    Scott David Daniels, Jun 20, 2006
    #6
  7. Girish Sahani

    Dan Bishop Guest

    MTD wrote:
    > > The system cannot
    > > accurately represent some integers,

    >
    > Er, I meant FLOATS. Doh.


    You were also right the first time. But it only applies to integers
    with more than 53 bits.
    Dan Bishop, Jun 20, 2006
    #7
  8. Girish Sahani

    Aahz Guest

    In article <>,
    Girish Sahani <> wrote:
    >
    >I want to truncate every number to 2 digits after the decimal point. I
    >tried the following but it doesnt work.
    >
    >>>> a = 2
    >>>> b = 3
    >>>> round(a*1.0 / b,2)

    >0.67000000000000004
    >
    >Inspite of specifying 2 in 2nd attribute of round, it outputs all the
    >digits after decimal.


    You should also consider switching to the decimal module if you care
    about getting correct results.
    --
    Aahz () <*> http://www.pythoncraft.com/

    "I saw `cout' being shifted "Hello world" times to the left and stopped
    right there." --Steve Gonedes
    Aahz, Jun 20, 2006
    #8
  9. Girish Sahani

    per9000 Guest

    Hi,

    just a thought: if you *always* work with "floats" with two decimals,
    you are in fact working with integers, but you represent them as a
    floats - confusing for the internal representation.

    So why not work with int(float * 100) instead? This way you only have
    to take care of roundoffs etc when dividing.

    "int (+|-|*) int" = int
    "int / int" = int / int + int % int

    Integers are nice, me like integers.

    /per9000
    per9000, Jun 21, 2006
    #9
  10. Girish Sahani

    per9000 Guest

    oops, should be something like this:

    "int / int" = "int / int, int % int"

    /per9000
    per9000, Jun 21, 2006
    #10
  11. > just a thought: if you *always* work with "floats" with two decimals,
    > you are in fact working with integers, but you represent them as a
    > floats - confusing for the internal representation.
    >
    > So why not work with int(float * 100) instead? This way you only have
    > to take care of roundoffs etc when dividing.

    And why won't you work with decimal module ?
    jean-michel bain-cornu, Jun 21, 2006
    #11
  12. In article <>,
    "per9000" <> writes:
    |>
    |> just a thought: if you *always* work with "floats" with two decimals,
    |> you are in fact working with integers, but you represent them as a
    |> floats - confusing for the internal representation.

    No, you aren't - you are working with fixed-point, which is something
    that is neither integers nor floating-point, but is somewhere in
    between. I am (just) old enough to remember when it was used for
    numeric work, and to have used it for that myself, but not old enough
    to have done any numeric work using fixed-point hardware.

    |> So why not work with int(float * 100) instead? This way you only have
    |> to take care of roundoffs etc when dividing.

    And multiplying, and calling most mathematical functions.


    Regards,
    Nick Maclaren.
    Nick Maclaren, Jun 21, 2006
    #12
  13. Girish Sahani

    per9000 Guest

    Nick Maclaren wrote:
    > |> just a thought: if you *always* work with "floats" with two decimals,
    > |> you are in fact working with integers, but you represent them as a
    > |> floats - confusing for the internal representation.
    >
    > No, you aren't - you are working with fixed-point


    Nick, your answer has so many layers, I'll try to explain how I think
    :-D

    1) if you use integers you can think of them as having one part bigger
    than 100 and one part smaller than 100, like so:
    >>> a = 11122
    >>> (a/100,a%100)

    (111, 22)
    Here the output 111,22 looks like something else than an integer, but
    this is just a matter of representation. a *is* an integer, but we
    represent it *as if it was* a "decimal" number. (Compare with
    (minutes,seconds) or (euro,cents) or (feet,inch) or any other
    "arbitrary" position system)

    2) If we use floats with two decimals
    >>> b = 222.33
    >>> b

    222.33000000000001
    they look like fix-point numbers (I had to look it up
    http://en.wikipedia.org/wiki/Fixed-point :-D) but python stores it
    (correct me if I am wrong) as a float (or double or quad or whatever).
    If we want to work with fix-point aritmetics we have to invent new
    functions to do most math.

    3) Most "decimal numbers" cannot be stored exactly as floats - that is
    why b gave the ugly print. But some can, f.x
    >>> quart = 0.25
    >>> quart

    0.25
    quart translates to a finite "decimal" number in binary (0.01 I think).

    The point is: representing should-be integers as floats makes you loose
    precision (negligable probalby but still...).

    4)
    > |> So why not work with int(float * 100) instead? This way you only have
    > |> to take care of roundoffs etc when dividing.
    >
    > And multiplying, and calling most mathematical functions.

    You are correct of course. My mistake.

    But, the multiplication is exact before you start rounding off - I wont
    start counting ordos for int*int vs. float*float, but it could have
    some advantages
    >>> a

    11122
    >>> b

    22233
    >>> a*b

    247275426
    >>> (a*b/10000,a*b%10000)

    (24727, 5426)
    On the other hand you will quickly loose accuracy if you perform
    multiple multiplications or divisions or use other mathematical
    functions.

    5) So, when could this way of thinking be useful? Well, rarely, but if
    you only add/subtract "decimals" and/or multiply "decimals" with whole
    numbers or if you want to use some non-metric system to do scientific
    stuff (compute square feet when having (feet1,inch1) * (feet2,inch2)
    assuming that inches are atomic.)

    This could of course be extended to
    (feet, inch, quarter_of_afoot, sixteeth_of_a_foot) if you'd like - it
    is all a matter of representation.

    Regards,
    Per
    ----
    "It is a gift. A gift to the foes of 'the Terrorists'. Why not
    use this 'terrorism'? Long has my father, 'George Bush Sr',
    kept the forces of 'the terrorists' at bay. By the blood of
    our people are your lands kept safe. Give 'the land of the
    brave' the weapon of the enemy. Let us use it against him."
    per9000, Jun 21, 2006
    #13
  14. Nick Maclaren wrote: (of fixed point)
    > .... I am (just) old enough to remember when it was used for
    > numeric work, and to have used it for that myself, but not old enough
    > to have done any numeric work using fixed-point hardware.


    You are using fixed point hardware today. Fixed point tracked the
    "decimal point" (or "binary point" or whatever) in the mind of the
    programmer, not in the state of the hardware. There never was
    "fixed point hardware," it was simply a way of viewing the results
    of the gates of the same hardware we use today.

    --
    --Scott David Daniels
    Scott David Daniels, Jun 21, 2006
    #14
  15. In article <44997ea8$>,
    Scott David Daniels <> writes:
    |> Nick Maclaren wrote: (of fixed point)
    |> > .... I am (just) old enough to remember when it was used for
    |> > numeric work, and to have used it for that myself, but not old enough
    |> > to have done any numeric work using fixed-point hardware.
    |>
    |> You are using fixed point hardware today. Fixed point tracked the
    |> "decimal point" (or "binary point" or whatever) in the mind of the
    |> programmer, not in the state of the hardware. There never was
    |> "fixed point hardware," it was simply a way of viewing the results
    |> of the gates of the same hardware we use today.

    Er, no. Analogue hardware never was fixed-point, and I have used that :)

    More relevantly, you are using a very parochial and unusual interpretation
    of the word 'hardware'. In normal usage, it includes everything below
    the instruct set specification (now often called the ABI). And I can
    assure you that there is a considerable difference between the hardware
    that provides a floating-point interface at the ABI and that which
    provides a fixed-point interface.


    Regards,
    Nick Maclaren.
    Nick Maclaren, Jun 21, 2006
    #15
  16. Girish Sahani

    rasonage

    Joined:
    Dec 17, 2011
    Messages:
    1
    similar problem

    floatVal = .4350001
    "%.2f" % floatVal

    To get .43 works great, but what if I wanted to have the decimal of what I truncate to be of variable input?
    it's not like it would work this way:

    accuracy = 2
    floatVal = .4350001

    "%.%if" %(floatVal, min_accuracy)

    I'm trying to get the pointer "accuracy" as a value that can be changed/entered via user input so users can change what decimal place to round to. How would I do that?
    rasonage, Dec 17, 2011
    #16
    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. Surjit Nameirakpam

    How to Round off and Truncate in ruby

    Surjit Nameirakpam, Nov 20, 2007, in forum: Ruby
    Replies:
    6
    Views:
    274
    Gavin Kistner
    Nov 20, 2007
  2. Shiping Zhang

    decimal round off issue

    Shiping Zhang, Sep 22, 2009, in forum: Perl Misc
    Replies:
    17
    Views:
    273
    Ilya Zakharevich
    Sep 28, 2009
  3. ஆமாசà¯à®šà¯

    round off to two decimal & return float

    ஆமாசà¯à®šà¯, Mar 30, 2013, in forum: Python
    Replies:
    2
    Views:
    132
    pyplexed
    Mar 30, 2013
  4. ஆமாசà¯à®šà¯

    Re: round off to two decimal & return float

    ஆமாசà¯à®šà¯, Mar 30, 2013, in forum: Python
    Replies:
    1
    Views:
    84
    Grant Edwards
    Mar 30, 2013
  5. Peter Otten
    Replies:
    0
    Views:
    92
    Peter Otten
    Mar 30, 2013
Loading...

Share This Page