round() to nearest .05 ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • tertius

    round() to nearest .05 ?

    Hi,

    I'm trying to round my float total to the nearest .05 cents.

    12.01 should produce 12.00
    0.14 should produce 0.10
    2.28 " 2.25
    703.81 " 703.80

    "%.02f"%100.009 9 produces 100.01 (which I know is right)
    No combination of round and/or "%.02f" works for me.

    What's the best way to get there? Should I write a function to manage my
    rounding or is there a simpler/better way?

    TIA
    T
  • Kent Johnson

    #2
    Re: round() to nearest .05 ?

    tertius wrote:[color=blue]
    > Hi,
    >
    > I'm trying to round my float total to the nearest .05 cents.[/color]

    If you want the *nearest* .05, this works:[color=blue][color=green][color=darkred]
    >>> def fivecents(f):[/color][/color][/color]
    .... return round(f*2.0, 1) / 2.0
    ....[color=blue][color=green][color=darkred]
    >>> for f in [ 12.01, 0.14, 2.28, 703.81]:[/color][/color][/color]
    .... print f, fivecents(f)
    ....
    12.01 12.0
    0.14 0.15
    2.28 2.3
    703.81 703.8
    [color=blue]
    > 12.01 should produce 12.00
    > 0.14 should produce 0.10
    > 2.28 " 2.25
    > 703.81 " 703.80[/color]

    Your example seems to be rounding down always, not what I would call
    nearest. Here is one that always rounds toward zero:[color=blue][color=green][color=darkred]
    >>> def lowerfivecents( f):[/color][/color][/color]
    .... return int(f*20) / 20.0
    ....[color=blue][color=green][color=darkred]
    >>> for f in [ 12.01, 0.14, 2.28, 703.81]:[/color][/color][/color]
    .... print f, lowerfivecents( f)
    ....
    12.01 12.0
    0.14 0.1
    2.28 2.25
    703.81 703.8

    If you want to always round toward more negative, use math.floor()
    instead of int().

    Kent[color=blue]
    >
    > "%.02f"%100.009 9 produces 100.01 (which I know is right)
    > No combination of round and/or "%.02f" works for me.
    >
    > What's the best way to get there? Should I write a function to manage my
    > rounding or is there a simpler/better way?
    >
    > TIA
    > T[/color]

    Comment

    • Bengt Richter

      #3
      Re: round() to nearest .05 ?

      On Mon, 15 Nov 2004 22:52:42 +0200, tertius <terti@mighty.c o.za> wrote:
      [color=blue]
      >Hi,
      >
      >I'm trying to round my float total to the nearest .05 cents.[/color]
      Nearest which way? IWT 2.28 is nearer 2.30 than 2.25 ;-)
      ISTM you are rounding _down_ to the nearest nickel. So you want to
      drop fractional nickels. Which int will do if you calculate the number
      of nickels. Then you can divide by 20. to get dollars again[color=blue]
      >
      >12.01 should produce 12.00
      > 0.14 should produce 0.10
      > 2.28 " 2.25
      >703.81 " 703.80
      >
      >"%.02f"%100.00 99 produces 100.01 (which I know is right)
      >No combination of round and/or "%.02f" works for me.
      >
      >What's the best way to get there? Should I write a function to manage my
      >rounding or is there a simpler/better way?[/color]

      One way, just to play with subclassing float for constrained initial value:
      [color=blue][color=green][color=darkred]
      >>> values = [12.01, 0.14, 2.28, 703.81]
      >>> class Nickels(float):[/color][/color][/color]
      ... def __new__(cls, val):
      ... return float.__new__(c ls, int(val*20.0)/20.)
      ... def __repr__(self): return '<Nickels %.2f>'%float(se lf)
      ...[color=blue][color=green][color=darkred]
      >>> [Nickels(v) for v in values][/color][/color][/color]
      [<Nickels 12.00>, <Nickels 0.10>, <Nickels 2.25>, <Nickels 703.80>][color=blue][color=green][color=darkred]
      >>> for value in values: print '%8.2f => %8.2f'%(value,N ickels(value))[/color][/color][/color]
      ...
      12.01 => 12.00
      0.14 => 0.10
      2.28 => 2.25
      703.81 => 703.80

      but it's probably silly compared to
      [color=blue][color=green][color=darkred]
      >>> def roundnickel(dol lars): return int(dollars*20. 0)/20.0[/color][/color][/color]
      ...[color=blue][color=green][color=darkred]
      >>> for value in values: print '%8.2f => %8.2f'%(value, roundnickel(val ue))[/color][/color][/color]
      ...
      12.01 => 12.00
      0.14 => 0.10
      2.28 => 2.25
      703.81 => 703.80

      What do you want to do for negative numbers? int "rounds" towards zero.
      [color=blue][color=green][color=darkred]
      >>> for value in -.01,.01,-.09,.09: print '%8.2f => %8.2f'%(value, roundnickel(val ue))[/color][/color][/color]
      ...
      -0.01 => 0.00
      0.01 => 0.00
      -0.09 => -0.05
      0.09 => 0.05

      BTW, if you wanted to use the class with all float operators, you'd have
      to define the methods one way or another (there's some sneaky ways, but I think
      the class is just a side trip ;-)
      [color=blue][color=green][color=darkred]
      >>> Nickels(.09)[/color][/color][/color]
      <Nickels 0.05>[color=blue][color=green][color=darkred]
      >>> Nickels(.09) + .01[/color][/color][/color]
      0.0600000000000 00005

      Being a subclass of float, python figured out how to coerce Nickels
      to float for the addition. If we add an adding method, we get
      [color=blue][color=green][color=darkred]
      >>> Nickels.__add__ = lambda self,other: Nickels(float(s elf)+ float(other))
      >>> Nickels(.09) + .01[/color][/color][/color]
      <Nickels 0.05>[color=blue][color=green][color=darkred]
      >>> Nickels(.09) + .06[/color][/color][/color]
      <Nickels 0.10>

      too much work ;-)

      Regards,
      Bengt Richter

      Comment

      • Diez B. Roggisch

        #4
        Re: round() to nearest .05 ?

        > What's the best way to get there? Should I write a function to manage my[color=blue]
        > rounding or is there a simpler/better way?[/color]

        Others have pointed out how to achieve the rounding - I just want to add
        that using floats for currency values isn't the best choice. Depending on
        your version of python, check out these links:


        The idea is to have a Decimal data type, for every use where decimals are needed but binary floating point is too inexact.



        --
        Regards,

        Diez B. Roggisch

        Comment

        • tertius

          #5
          Re: round() to nearest .05 ?

          tertius wrote:[color=blue]
          > Hi,
          >
          > I'm trying to round my float total to the nearest .05 cents.
          >
          > 12.01 should produce 12.00
          > 0.14 should produce 0.10
          > 2.28 " 2.25
          > 703.81 " 703.80
          >
          > "%.02f"%100.009 9 produces 100.01 (which I know is right)
          > No combination of round and/or "%.02f" works for me.
          >
          > What's the best way to get there? Should I write a function to manage my
          > rounding or is there a simpler/better way?
          >
          > TIA
          > T[/color]

          Thanks for all the help!
          I meant nearest towards zero.

          chrs
          T

          Comment

          Working...