舍入到最接近的整数

时间:2015-08-04 19:51:39

标签: python

我一直试图绕过长长的浮动数字,如:

32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...

到目前为止没有成功。我尝试了math.ceil(x)math.floor(x)(虽然这会向上或向下舍入,这不是我正在寻找的)和round(x)也没有工作(仍然浮点数。)

我该怎么办?

编辑:代码:

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)

11 个答案:

答案 0 :(得分:268)

int(round(x))

将它舍入并将其更改为整数

编辑:

您没有将int(round(h))赋值给任何变量。当你调用int(round(h))时,它返回整数但不执行任何其他操作;你必须改变这一行:

h = int(round(h))

将新值分配给h

答案 1 :(得分:19)

使用round(x, y)。它会将您的数字向上舍入到您想要的小数位。

例如:

>>> round(32.268907563, 3)
32.269

答案 2 :(得分:15)

round(value,significantDigit)是普通的解决方案,但是当圆形值以5结尾时,这不会像数学角度那样运算。如果5位于您四舍五入的数字之后的数字中,则这些值有时仅按预期向上舍入(即8.005四舍五入到两位小数给出8.01)。对于由于浮点数学的怪癖而导致的某些值,它们会向下舍入!

>>> 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

怪异。

假设您的意图是对科学中的统计数据进行传统舍入,这是一个方便的包装器,可以使round函数按预期工作,需要import额外的内容,例如Decimal

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*5),2)

0.08

啊哈!所以基于此,我们可以创建一个函数......

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

基本上,这会增加一个值,保证小于您尝试使用round的字符串的最小给定数字。通过添加少量数量,它在大多数情况下保留了round的行为,同时现在确保数字低于被舍入的数字是5它是否会向上舍入,如果是{{1}它向下舍入。

使用4的方法是故意的,因为它是您可以添加的最大小数字以强制转换,同时还确保您添加的值永远不会更改舍入,即使小数10**(-len(val)-1)不见了。我可以使用.与条件10**(-len(val))一起减去if (val>1)更多......但更简单的是总是减去1,因为这不会改变很多适用此变通方法可以正确处理的十进制数范围。如果您的值达到类型的限制,此方法将失败,这将失败,但对于几乎整个有效小数值范围,它应该有效。

您也可以使用decimal库来完成此任务,但我建议的包装器更简单,在某些情况下可能更受欢迎。

修改:感谢Blckknght指出1边缘情况仅针对特定值发生。此答案的早期版本也不够明确,只有当数字紧跟您正在四舍五入的数字后面的数字具有5 时才会出现奇怪的舍入行为

答案 3 :(得分:10)

对于积极因素,请尝试

int(x + 0.5)

要使其适用于否定,请尝试

int(x + (0.5 if x > 0 else -0.5))

int()就像一个floor函数,因此你可以利用这个属性。这绝对是最快的方式。

答案 4 :(得分:9)

按照round half to even的规定,不只是Python正在执行IEEE 754吗?

小心重新定义,或使用“非标准”舍入......

(另见https://stackoverflow.com/a/33019948/109839

答案 5 :(得分:4)

你也可以使用numpy假设你使用python3.x这里是一个例子

import numpy as np
x = 2.3
print(np.rint(x))
>>> 2.0

答案 6 :(得分:1)

如果您需要(例如)A的两位数近似值,那么 int(A*100+0.5)/100.0会做你想要的。

如果你需要三位数近似乘以并除以1000,依此类推。

答案 7 :(得分:1)

您的解决方案在不指定第二个参数(小数位数)的情况下进行回合

>>> round(0.44)
0
>>> round(0.64)
1

好得多
>>> int(round(0.44, 2))
0
>>> int(round(0.64, 2))
0

摘自https://docs.python.org/3/library/functions.html#round的Python文档

  

round(number [,ndigits])

     

小数点后的返回数字四舍五入为n位精度。如果   ndigits被省略或为None,它返回与其最接近的整数   输入。

     

注意

     

float的round()行为可能令人惊讶:例如,   round(2.675,2)得到2.67,而不是预期的2.68。这不是   错误:这是因为大多数小数点不能为   精确地表示为浮点数。请参阅浮点算法:问题   和限制以获取更多信息。

答案 8 :(得分:1)

类似的事情也应该起作用

import numpy as np    

def proper_round(a):
    '''
    given any real number 'a' returns an integer closest to 'a'
    '''
    a_ceil = np.ceil(a)
    a_floor = np.floor(a)
    if np.abs(a_ceil - a) < np.abs(a_floor - a):
        return int(a_ceil)
    else:
        return int(a_floor)

答案 9 :(得分:0)

为此,我建议您做以下事情-

int(round(x))

这将为您提供最接近的整数。

希望这会有所帮助!

答案 10 :(得分:0)

我使用并建议以下解决方案(python3.6):

y = int(x + (x % (1 if x >= 0 else -1)))

它可以很好地处理半数(正数和负数),甚至比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
===========