为什么Python的圆形如此奇怪?

sam*_*sam 9 python floating-point rounding

我的代码:

  #!/usr/bin/python
  # -*- coding: utf-8 -*-
  print (round(1.555, 1))  # It seems normal
  print (round(1.555, 2))  # Why it is not output 1.56?
  print (round(1.556, 2))  # It seems normal
Run Code Online (Sandbox Code Playgroud)

输出:

  sam@sam:~/code/python$ ./t2.py
  1.6
  1.55
  1.56
  sam@sam:~/code/python$
Run Code Online (Sandbox Code Playgroud)

round(1.555, 1)输出1.6.

为什么不round(1.555, 2)输出1.56

Ble*_*der 12

看看文档:

注意round()浮动的行为可能会令人惊讶:例如,round(2.675, 2)给出2.67而不是预期的行为 2.68.这不是一个错误:这是因为大多数小数部分不能完全表示为浮点数.有关详细信息,请参阅浮点运算:问题和限制.

如果你继续挖掘(即点击该链接),你会发现一个类似于你的例子:

内置round()函数的文档说它会舍入到最接近的值,从零开始四舍五入.由于小数部分2.675正好位于2.67和之间2.68,因此您可能希望此结果为(二进制近似) 2.68.它不是,因为当十进制字符串2.675转换为二进制浮点数时,它再次被二进制近似替换,其精确值是

2.67499999999999982236431605997495353221893310546875
Run Code Online (Sandbox Code Playgroud)

字符串格式也不能解决您的问题.浮点数不会按照您预期的方式存储:

>>> '{:0.2f}'.format(1.555)
'1.55'
Run Code Online (Sandbox Code Playgroud)

这不是一个"修复",但Python确实有一个decimal模块,它是专为浮点运算而设计的:

>>> from decimal import Decimal
>>> n = Decimal('1.555')
>>> round(n, 2)
Decimal('1.56')
Run Code Online (Sandbox Code Playgroud)


Hun*_*len 6

直接来自文档:

round()对于浮点数的行为可能会令人惊讶:例如,round(2.675,2)给出2.67而不是预期的2.68.这不是一个错误:这是因为大多数小数部分不能完全表示为浮点数.有关详细信息,请参阅浮点运算:问题和限制.