Python 四舍五入到最接近的整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31818050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Round number to nearest integer
提问by vandernath
I've been trying to round long float numbers like:
我一直在尝试舍入长浮点数,例如:
32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...
With no success so far. I tried math.ceil(x)
, math.floor(x)
(although that would round up or down, which is not what I'm looking for) and round(x)
which didn't work either (still float numbers).
到目前为止没有成功。我试过math.ceil(x)
,math.floor(x)
(虽然这会向上或向下取整,这不是我要找的),round(x)
但也不起作用(仍然是浮点数)。
What could I do?
我能做什么?
EDIT: CODE:
编辑:代码:
for i in widthRange:
for j in heightRange:
r, g, b = rgb_im.getpixel((i, j))
h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)
h = h * 360
int(round(h))
print(h)
采纳答案by francisco sollima
int(round(x))
Will round it and change it to integer
将它舍入并将其更改为整数
EDIT:
编辑:
You are not assigning int(round(h)) to any variable. When you call int(round(h)), it returns the integer number but does nothing else; you have to change that line for:
您没有将 int(round(h)) 分配给任何变量。当您调用 int(round(h)) 时,它返回整数但不执行任何其他操作;您必须更改该行:
h = int(round(h))
To assign the new value to h
将新值分配给 h
EDIT 2:
编辑2:
As @plowman said in the comments, Python's round()
doesn't work as one would normally expect, and that's because the way the number is stored as a variable is ussually not the way you see it on screen. There are lots of answers that explain this behavior:
正如@plowman 在评论中所说,Pythonround()
不像人们通常期望的那样工作,那是因为数字作为变量存储的方式通常与您在屏幕上看到的方式不同。有很多答案可以解释这种行为:
round() in Python doesn't seem to be rounding properly
One way to avoid this problem is to use the Decimal as stated by this answer: https://stackoverflow.com/a/15398691/4345659
避免此问题的一种方法是使用此答案所述的十进制:https: //stackoverflow.com/a/15398691/4345659
In order for this answer to work properly without using extra libraries it would be convenient to use a custom rounding function. After a lot of corrections, I came up with the following solution, that as far as I tested avoided all the storing issues. It is based on using the string representation, obtained with repr()
(NOT str()
!). It looks hacky but it was the only way I found to solve all the cases. It works with both Python2 and Python3.
为了使这个答案在不使用额外库的情况下正常工作,使用自定义舍入函数会很方便。经过大量更正后,我想出了以下解决方案,据我测试,它避免了所有存储问题。它基于使用字符串表示,通过repr()
(NOT str()
!) 获得。它看起来很笨拙,但这是我发现解决所有案例的唯一方法。它适用于 Python2 和 Python3。
def proper_round(num, dec=0):
num = str(num)[:str(num).index('.')+dec+2]
if num[-1]>='5':
return float(num[:-2-(not dec)]+str(int(num[-2-(not dec)])+1))
return float(num[:-1])
Tests:
测试:
>>> print(proper_round(1.0005,3))
1.001
>>> print(proper_round(2.0005,3))
2.001
>>> print(proper_round(3.0005,3))
3.001
>>> print(proper_round(4.0005,3))
4.001
>>> print(proper_round(5.0005,3))
5.001
>>> print(proper_round(1.005,2))
1.01
>>> print(proper_round(2.005,2))
2.01
>>> print(proper_round(3.005,2))
3.01
>>> print(proper_round(4.005,2))
4.01
>>> print(proper_round(5.005,2))
5.01
>>> print(proper_round(1.05,1))
1.1
>>> print(proper_round(2.05,1))
2.1
>>> print(proper_round(3.05,1))
3.1
>>> print(proper_round(4.05,1))
4.1
>>> print(proper_round(5.05,1))
5.1
>>> print(proper_round(1.5))
2.0
>>> print(proper_round(2.5))
3.0
>>> print(proper_round(3.5))
4.0
>>> print(proper_round(4.5))
5.0
>>> print(proper_round(5.5))
6.0
>>>
>>> print(proper_round(1.000499999999,3))
1.0
>>> print(proper_round(2.000499999999,3))
2.0
>>> print(proper_round(3.000499999999,3))
3.0
>>> print(proper_round(4.000499999999,3))
4.0
>>> print(proper_round(5.000499999999,3))
5.0
>>> print(proper_round(1.00499999999,2))
1.0
>>> print(proper_round(2.00499999999,2))
2.0
>>> print(proper_round(3.00499999999,2))
3.0
>>> print(proper_round(4.00499999999,2))
4.0
>>> print(proper_round(5.00499999999,2))
5.0
>>> print(proper_round(1.0499999999,1))
1.0
>>> print(proper_round(2.0499999999,1))
2.0
>>> print(proper_round(3.0499999999,1))
3.0
>>> print(proper_round(4.0499999999,1))
4.0
>>> print(proper_round(5.0499999999,1))
5.0
>>> print(proper_round(1.499999999))
1.0
>>> print(proper_round(2.499999999))
2.0
>>> print(proper_round(3.499999999))
3.0
>>> print(proper_round(4.499999999))
4.0
>>> print(proper_round(5.499999999))
5.0
Finally, the corrected answer would be:
最后,更正的答案是:
# Having proper_round defined as previously stated
h = int(proper_round(h))
EDIT 3:
编辑 3:
Tests:
测试:
>>> proper_round(6.39764125, 2)
6.31 # should be 6.4
>>> proper_round(6.9764125, 1)
6.1 # should be 7
The gotcha here is that the dec
-th decimal can be 9 and if the dec+1
-th digit >=5 the 9 will become a 0 and a 1 should be carried to the dec-1
-th digit.
这里的问题是,第dec
-th 位小数可以是 9,如果第dec+1
-th 位数字 >=5,则 9 将变成 0,并且应该将 1 带到dec-1
第 -th 位数字。
If we take this into consideration, we get:
如果我们考虑到这一点,我们会得到:
def proper_round(num, dec=0):
num = str(num)[:str(num).index('.')+dec+2]
if num[-1]>='5':
a = num[:-2-(not dec)] # integer part
b = int(num[-2-(not dec)])+1 # decimal part
return float(a)+b**(-dec+1) if a and b == 10 else float(a+str(b))
return float(num[:-1])
In the situation described above b = 10
and the previous version would just concatenate a
and b
which would result in a concatenation of 10
where the trailing 0 would disappear. This version transforms b
to the right decimal place based on dec
, as a proper carry.
在上述情况下b = 10
,之前的版本只会串联a
,b
这将导致10
尾随 0 消失的串联。此版本b
根据dec
,转换为正确的小数位,作为适当的进位。
回答by Satyaki Sanyal
Use round(x, y)
. It will round up your number up to your desired decimal place.
使用round(x, y)
. 它会将您的数字四舍五入到您想要的小数位。
For example:
例如:
>>> round(32.268907563, 3)
32.269
回答by Jason R. Mick
round(value,significantDigit)
is the ordinary solution, however this does not operate as one would expect from a math perspective when round values ending in 5
. If the 5
is in the digit just after the one you're rounded to, these values are only sometimes rounded up as expected (i.e. 8.005
rounding to two decimal digits gives 8.01
). For certain values due to the quirks of floating point math, they are rounded down instead!
round(value,significantDigit)
是普通的解决方案,但是当舍入值以5
. 如果5
是在您四舍五入后的数字中,则这些值有时只会按预期8.005
四舍五入(即四舍五入为两位十进制数字给出8.01
)。对于由于浮点数学的怪癖而导致的某些值,它们被四舍五入了!
i.e.
IE
>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01
Weird.
奇怪的。
Assuming your intent is to do the traditional rounding for statistics in the sciences, this is a handy wrapper to get the round
function working as expected needing to import
extra stuff like Decimal
.
假设您的目的是对科学中的统计进行传统的舍入,这是一个方便的包装器,可以让round
函数按预期工作,需要import
额外的东西,如Decimal
.
>>> round(0.075,2)
0.07
>>> round(0.075+10**(-2*5),2)
0.08
Aha! So based on this we can make a function...
啊哈!所以基于此我们可以创建一个函数......
def roundTraditional(val,digits):
return round(val+10**(-len(str(val))-1), digits)
Basically this adds a value guaranteed to be smaller than the least given digit of the string you're trying to use round
on. By adding that small quantity it preserve's round
's behavior in most cases, while now ensuring if the digit inferior to the one being rounded to is 5
it rounds up, and if it is 4
it rounds down.
基本上,这会增加一个值,该值保证小于您尝试使用的字符串的最小给定数字round
。通过添加少量,它round
在大多数情况下保留了 的行为,同时确保低于四舍五入的数字是否5
向上四舍五入,如果是4
则向下四舍五入。
The approach of using 10**(-len(val)-1)
was deliberate, as it the largest small number you can add to force the shift, while also ensuring that the value you add never changes the rounding even if the decimal .
is missing. I could use just 10**(-len(val))
with a condiditional if (val>1)
to subtract 1
more... but it's simpler to just always subtract the 1
as that won't change much the applicable range of decimal numbers this workaround can properly handle. This approach will fail if your values reaches the limits of the type, this will fail, but for nearly the entire range of valid decimal values it should work.
使用的方法是10**(-len(val)-1)
经过深思熟虑的,因为它是您可以添加的最大小数以强制移位,同时还确保即使.
缺少小数点,您添加的值也不会改变舍入。我可以只10**(-len(val))
使用一个条件if (val>1)
来减去1
更多......但总是减去更简单,1
因为这不会改变这个解决方法可以正确处理的十进制数的适用范围。如果您的值达到类型的限制,则此方法将失败,这将失败,但对于几乎整个有效十进制值范围,它都应该有效。
You can also use the decimallibrary to accomplish this, but the wrapper I propose is simpler and may be preferred in some cases.
您也可以使用十进制库来完成此操作,但我建议的包装器更简单,并且在某些情况下可能是首选。
Edit:Thanks Blckknghtfor pointing out that the 5
fringe case occurs only for certain values. Also an earlier version of this answer wasn't explicit enough that the odd rounding behavior occurs only when the digit immediately inferior to the digit you're rounding to has a 5
.
编辑:感谢Blckknght指出5
边缘情况仅发生在某些值。此外,此答案的早期版本不够明确,只有当数字立即低于您要舍入的数字时,才会发生5
奇数舍入行为。
回答by Mapio
Isn't just Python doing round half to even, as prescribed by IEEE 754?
不只是 Python按照IEEE 754 的规定进行了一半到一半的操作吗?
Be careful redefining, or using "non-standard" rounding…
小心重新定义,或使用“非标准”舍入……
(See also https://stackoverflow.com/a/33019948/109839)
回答by Confuse
For positives, try
对于积极的,尝试
int(x + 0.5)
To make it work for negatives too, try
为了使它也适用于底片,请尝试
int(x + (0.5 if x > 0 else -0.5))
int()
works like a floor function and hence you can exploit this property. This is definitely the fastest way.
int()
像地板函数一样工作,因此您可以利用此属性。这绝对是最快的方式。
回答by Hoo
If you need (for example) a two digit approximation for A, then
int(A*100+0.5)/100.0
will do what you are looking for.
如果您需要(例如)A 的两位数近似值,则
int(A*100+0.5)/100.0
可以满足您的要求。
If you need three digit approximation multiply and divide by 1000 and so on.
如果你需要三位数的近似乘除以 1000 等等。
回答by sushmit
You can also use numpy assuming if you are using python3.x here is an example
你也可以使用 numpy 假设你使用的是 python3.x 这里是一个例子
import numpy as np
x = 2.3
print(np.rint(x))
>>> 2.0
回答by rahul ranjan
For this purpose I would suggest just do the following thing -
为此,我建议只做以下事情-
int(round(x))
This will give you nearest integer.
这将为您提供最接近的整数。
Hope this helps!!
希望这可以帮助!!
回答by Jay
Your solution is calling round without specifying the second argument (number of decimal places)
您的解决方案是在不指定第二个参数(小数位数)的情况下调用 round
>>> round(0.44)
0
>>> round(0.64)
1
which is a much better result than
这是一个比
>>> int(round(0.44, 2))
0
>>> int(round(0.64, 2))
0
From the Python documentation at https://docs.python.org/3/library/functions.html#round
来自https://docs.python.org/3/library/functions.html#round的 Python 文档
round(number[, ndigits])
Return number rounded to ndigits precision after the decimal point. If ndigits is omitted or is None, it returns the nearest integer to its input.
Note
The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it's a result of the fact that most decimal fractions can't be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
回合(数字[,ndigits])
返回小数点后四舍五入到 ndigits 精度的数字。如果 ndigits 被省略或为 None,则返回与其输入最接近的整数。
笔记
浮点数的 round() 行为可能令人惊讶:例如,round(2.675, 2) 给出 2.67 而不是预期的 2.68。这不是错误:这是大多数十进制分数不能完全表示为浮点数的结果。有关更多信息,请参阅浮点运算:问题和限制。
回答by Василий Прядченко
I use and may advise the following solution (python3.6):
我使用并可能建议以下解决方案(python3.6):
y = int(x + (x % (1 if x >= 0 else -1)))
It works fine for half-numbers (positives and negatives) and works even faster than int(round(x)):
它适用于半数(正数和负数),并且比 int(round(x)) 更快:
round_methods = [lambda x: int(round(x)),
lambda x: int(x + (x % (1 if x >= 0 else -1))),
lambda x: np.rint(x).astype(int),
lambda x: int(proper_round(x))]
for rm in round_methods:
%timeit rm(112.5)
Out:
201 ns ± 3.96 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
159 ns ± 0.646 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
925 ns ± 7.66 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
1.18 μs ± 8.66 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
for rm in round_methods:
print(rm(112.4), rm(112.5), rm(112.6))
print(rm(-12.4), rm(-12.5), rm(-12.6))
print('=' * 11)
Out:
112 112 113
-12 -12 -13
===========
112 113 113
-12 -13 -13
===========
112 112 113
-12 -12 -13
===========
112 113 113
-12 -13 -13
===========