Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
rounding question
#11
Quote:if you do int( x + 0.50) , this will produce a floor() or a ceil() depending on the value of the decimal.
This actually does the same thing as round(). The trick of int(x + 0.50) was created for languages that don't have a round() function, but Python does have a round().
Reply
#12
(Apr-11-2020, 08:41 AM)DPaul Wrote: Thanks, but no, that is not what i am looking for.

Could you give some examples?

5.25 => ?
5.49 => ?
5.50 => ?
5.75 => ?

Quote:So i am wondering if python offers a function that will do this without adding the 0.50.
It seems like the round() that was mentioned earlier would fit, but perhaps there's a case that doesn't for some reason.
Reply
#13
(Apr-11-2020, 04:25 PM)bowlofred Wrote: It seems like the round() that was mentioned earlier would fit, but perhaps there's a case that doesn't for some reason.

Yes, there are cases that don't fit. Look at this. Is this what you learned at school about rounding?
>>> round(0.5)
0
>>> round(1.5)
2
>>> round(2.5)
2
>>> round(3.5)
4
>>> round(4.5)
4
Reply
#14
It's the default rounding mode in IEEE-754 floating point https://en.wikipedia.org/wiki/IEEE_754#R...to_nearest

If you want to use "ties round away from zero" instead, I'd probably just code my own as you've done. Another solution would be to use the decimal module. But using that and setting up the context to use the alternate rounding isn't compact. Fine if you're doing a lot of math, but not something I'd bother with for a single calculation. Something like this:

from decimal import *

print(Decimal(0.5).to_integral_value())  # With default context, will round to even and print 0
setcontext(Context(rounding=ROUND_HALF_UP))
print(Decimal(0.5).to_integral_value())  # With new context, will round up and print 1
The decimal module has several different rounding methods. Rounding modes in decimal
Reply
#15
OK, int() is not random, obviously.
But i pointed out that " we may be distributing a series of costs over eg. 5 departments",
each cost divided by 5 wil produce a different decimal.
Sometimes less than .50 sometimes .50 or more.
That fact is random because the list of costs is what it is, all different, resulting in different decimal results.

So you may want to round to the nearest integer, if that is the company policy.
The only way i know is: to add to the result of the division 0.50

I'm sure that if < .050 do int() and if >.49 do ceil() is a non-starter. :-)

The only thing i want to know is, if i missed something.
Python offers something like ceil() which i can easily reproduce by doing int(x.y + 1)
Do we have something that will give the nearest integer ?

thx,
Paul
Reply
#16
There are different ways to round numbers. The way that Python does it is far more accurate than using the simple method you learned in the 5th grade. When processing large amounts of data, accuracy is important. The program below generates 10,000,000 random samples from 0 to 1000 in steps of .25. It rounds the numbers to the nearest integer, first by ties rounding away from zero (as done in the OP) and then ties rounding towards even (as Python does it). Then it prints the average of both methods, and then the error between the accumulated total of rounded values and the true total of unrounded value. The closer to 0 these values are, the more accurate the result. The program might take a few minutes depending on the speed of your computer
import random
real_total = 0.0
round_away = 0.0
round_even = 0.0

sample_size = 10000000

for i in range(0, sample_size):
    number = random.randrange(0,4000) / 4
    real_total += number
    round_away += int(number + 0.5)
    round_even += round(number)

avg_away = round_away/sample_size
avg_even = round_even/sample_size

error_away = round_away - real_total
error_even = round_even - real_total

print("average using round away from zero = ",avg_away)
print("average using round toward even = ",avg_even)
print("error using round away from zero =",error_away)
print("error using round toward even =",error_even)
Output:
average using round away from zero = 500.1346217 average using round toward even = 500.0095575 error using round away from zero = 1249678.25 error using round toward even = -963.75
In ties away from zero, you have four difference possibilities.
Output:
decimal value | .00| .25| .50| .75 difference | 0|-.25|+.50|+.25
So the average error would be (0-.25+.50+.25)/4.0 = +.125, which, over 10,000,000 samples will produce an overage of approximately 1250000, very close to the error reported by our program.
In ties toward even, you have eight different possibilities
Output:
E = even integer, O = Odd integer decimal value |E.00|O.00|E.25|O.25|E.50|O.50|E.75|O.75 difference | 0| 0|-.25|-.25|-.50|+.50|+.25|+.25
The average error would be (0+0-.25-.25-.50+.50+.25+.25)/8 = 0, so the errors will most of the time cancel each other out and give you an error close to 0. In the run above, the error was short by 963.75, that is .00096375%, very close to 0.
Reply
#17
Thank you Mr. Toad, i think we have a conlusion: there is no special function that will do the "+ .50" trick.
And if there is, nobody knows it.


But now you raise a different issue, that was not part of the original question.
I have never said that after distribution i would accept a difference from the original amounts! I only said I like integers.
It is fair to say that there are very few accountants reading this post. :-)

Because this is about the age old problem of "how to distribute x amounts over y recepients, in a fair manner".
Sloppy systems divide by y-recepients, round, and stuff the residue into the last recepient's amount, or post it under "calculating differences".

Surely, clever guys can think out of the box and find an easy way to balance everything. With 1_000_000 samples or with just one. :-)
to be distributed amongst 5, 17, 99 or... any number of recepients.

Paul
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  need help rounding joseph202020 7 1,257 Feb-21-2023, 08:13 PM
Last Post: joseph202020
  from numpy array to csv - rounding SchroedingersLion 6 2,063 Nov-14-2022, 09:09 PM
Last Post: deanhystad
  Random data generation sum to 1 by rounding juniorcoder 9 3,347 Oct-20-2021, 03:36 PM
Last Post: deanhystad
  Rounding issue kmll 1 1,379 Oct-08-2021, 10:35 AM
Last Post: Yoriz
  Not rounding to desired decimal places? pprod 2 2,504 Mar-05-2021, 11:11 AM
Last Post: pprod
  Decimal Rounding error project_science 4 2,696 Jan-06-2021, 03:14 PM
Last Post: project_science
  rounding and floats Than999 2 3,046 Oct-26-2020, 09:36 PM
Last Post: deanhystad
  Rounding to the nearest eight wallgraffiti 2 2,019 Jul-15-2020, 06:05 PM
Last Post: wallgraffiti
  price + tax rounding mlieqo 11 6,333 Sep-21-2019, 04:53 PM
Last Post: mlieqo
  rounding floats to a number of bits Skaperen 2 2,271 Sep-13-2019, 04:37 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020