舍入到最接近的整数

2024-05-19 03:41:33 发布

您现在位置: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)

Tags: 方法代码in编辑formathrgb浮点数
3条回答
int(round(x))

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

编辑:

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

h = int(round(h))

将新值赋给h

编辑2:

正如@prowleman在评论中所说,Python的round()并不像人们通常期望的那样工作,这是因为数字作为变量存储的方式通常不是您在屏幕上看到的方式。有很多答案可以解释这种行为:

round() in Python doesn't seem to be rounding properly

避免这个问题的一种方法是使用这个答案中的小数:https://stackoverflow.com/a/15398691/4345659

为了使这个答案在不使用额外库的情况下正常工作,可以方便地使用自定义舍入函数。经过大量修改,我提出了以下解决方案,只要我测试,就避免了所有的存储问题。它基于使用字符串表示,通过repr()(而不是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])

测试:

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

最后,正确的答案是:

# Having proper_round defined as previously stated
h = int(proper_round(h))

编辑3:

测试:

>>> proper_round(6.39764125, 2)
6.31 # should be 6.4
>>> proper_round(6.9764125, 1)
6.1  # should be 7

这里的问题是,第dec个十进制数可以是9,如果第dec+1个数字>;=5,9将变成0,1应该被带到第dec-1个数字。

如果我们考虑到这一点,我们会得到:

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

在上面描述的情况下,b = 10和上一个版本将只连接ab,这将导致10的连接,其中尾随的0将消失。此版本将b转换为基于dec的右小数位,作为适当的进位。

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它会向上舍入,如果是4它会向下舍入。

使用10**(-len(val)-1)的方法是经过深思熟虑的,因为它是您可以添加以强制移位的最大小数值,同时还确保添加的值永远不会更改舍入,即使缺少小数.。我可以用10**(-len(val))和条件if (val>1)来减去1更多。。。但是总是减去1比较简单,因为这不会改变这个解决方案能够正确处理的十进制数的适用范围。如果您的值达到类型的限制,这种方法将失败,但对于几乎所有有效的十进制值范围,它都应该起作用。

您也可以使用decimal库来实现这一点,但我建议的包装器更简单,在某些情况下可能更受欢迎。


编辑:感谢Blckknght指出5边缘情况只发生在某些值上。此外,这个答案的早期版本不够明确,只有当紧靠要舍入到的数字下面的数字有5时,才会出现奇数舍入行为

使用round(x, y)。它会把你的数字四舍五入到你想要的小数位。

例如:

>>> round(32.268907563, 3)
32.269

相关问题 更多 >

    热门问题