在Python中舍入到第二个小数位

use*_*589 46 python rounding

如何在python中将数字向上舍入到第二个小数位?例如:

0.022499999999999999

应该最高可达0.03

0.1111111111111000

应该最高可达0.12

如果在小数点后三位有任何值,我希望它总是向上舍入,留下小数点后面的2个值.

sim*_*ona 49

Python包含的round()功能允许您指定所需的位数.从文档:

round(x[, n])

将浮点值x舍入为小数点后的n位数.如果省略n,则默认为零.结果是一个浮点数.数值四舍五入为10的最接近倍数,功率减去n; 如果两个倍数相等,则舍入远离0(因此,例如,round(0.5)为1.0,round(-0.5)为-1.0).

所以你想round(x, 2)用来做正常的舍入.要确保数字始终向上舍入,您需要使用该ceil(x)函数.同样,要向下舍入使用floor(x).

  • 很好的建议,但它不会像OP似乎需要的那样四舍五入**. (8认同)

Edw*_*win 27

from math import ceil

num = 0.1111111111000
num = ceil(num * 100) / 100.0
Run Code Online (Sandbox Code Playgroud)

请参阅:
math.ceil文档
round文档 - 您可能希望无论如何都要查看它以供将来参考

  • 在以下情况下给出错误的结果:`math.ceil((1.11*100.0))/ 100.0`出现为`1.12`因为:`1.11*100.0`的值为`111.00000000000001` (6认同)
  • @nimeshkiranverma 看到 [浮点数学被破坏了吗?](/sf/ask/41160311/) 使用 [`decimal` 模块](https://docs.python .org/3/library/decimal.html) 如果您需要精确的十进制结果。 (2认同)

Pat*_*ini 14

根据埃德温的回答推断:

from math import ceil, floor
def float_round(num, places = 0, direction = floor):
    return direction(num * (10**places)) / float(10**places)
Run Code Online (Sandbox Code Playgroud)

使用:

>>> float_round(0.21111, 3, ceil)  #round up
>>> 0.212
>>> float_round(0.21111, 3)        #round down
>>> 0.211
>>> float_round(0.21111, 3, round) #round naturally
>>> 0.211
Run Code Online (Sandbox Code Playgroud)

  • 在以下情况下给出错误的结果:`math.ceil((1.11*100.0))/ 100.0`出现为`1.12`因为:`1.11*100.0`的值为`111.00000000000001` (5认同)

ajp*_*619 12

这取决于您在考虑正数和负数时所需的行为,但如果您想要总是向更大值舍入的内容(例如2.0449 - > 2.05, - 2.0449 - > -2.04),那么您可以执行以下操作:

round(x + 0.005, 2)
Run Code Online (Sandbox Code Playgroud)

还是有点发烧友:

def round_up(x, place):
    return round(x + 5 * 10**(-1 * (place + 1)), place)
Run Code Online (Sandbox Code Playgroud)

这似乎也起作用如下:

round(144, -1)
# 140
round_up(144, -1)
# 150
round_up(1e308, -307)
# 1.1e308
Run Code Online (Sandbox Code Playgroud)


Mar*_*som 11

x = math.ceil(x * 100.0) / 100.0
Run Code Online (Sandbox Code Playgroud)

  • 在我意识到这比我的解决方案更 Pythonic 之前,我不得不盯着它看了一会儿。 (2认同)

小智 5

请注意,该ceil(num * 100) / 100技巧会在某些退化输入上崩溃,例如 1e308。这可能不会经常出现,但我可以告诉你它只花了我几天时间。为了避免这种情况,“如果”ceil()floor()采用小数位参数就好了,就像round()......同时,有人知道一个不会在这样的输入上崩溃的干净替代方案吗?我对这个decimal包抱有一些希望,但它似乎也死了:

>>> from math import ceil
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP
>>> num = 0.1111111111000
>>> ceil(num * 100) / 100
0.12
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
0.12
>>> num = 1e308
>>> ceil(num * 100) / 100
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
Run Code Online (Sandbox Code Playgroud)

当然,有人可能会说崩溃是此类输入的唯一合理行为,但我认为导致问题的不是舍入而是乘法(这就是为什么,例如 1e306 不会崩溃),以及更清晰的实现舍入第 n 位 fn 将避免乘法黑客。


Jam*_*Lin 5

pythonround函数的舍入方式可能与您预期的不同。

您可以使用以下方法更具体地了解舍入方法Decimal.quantize

例如。

from decimal import Decimal, ROUND_HALF_UP
res = Decimal('0.25').quantize(Decimal('0.0'), rounding=ROUND_HALF_UP)
print(res) 
# prints 0.3
Run Code Online (Sandbox Code Playgroud)

更多参考:

https://gist.github.com/jackiekazil/6201722