【发布时间】:2017-07-13 14:19:20
【问题描述】:
首先我想提一下,这个问题不是重复的:
Python Rounding Inconsistently
我了解 IEEE 754 并且我知道:
简单的“总是向上取整 0.5”技术会导致稍微偏向较大的数字。通过大量计算,这可能很重要。 Python 3.0 方法消除了这个问题。
我同意 ROUND_HALF_UP 方法不如 Python 默认实现的方法。然而,有些人不知道这一点,如果规范需要,则需要使用该方法。完成这项工作的简单方法是:
def round_my(num, precission):
exp = 2*10**(-precission)
temp = num * exp
if temp%2 < 1:
return int(temp - temp%2)/exp
else:
return int(temp - temp%2 + 2)/exp
但我的考虑是 这不是 Pythonic...根据docs 我应该使用类似的东西:
def round_my(num, pricission):
N_PLACES = Decimal(10) ** pricission # same as Decimal('0.01')
# Round to n places
Decimal(num).quantize(N_PLACES)
问题是这不会通过所有测试用例:
class myRound(unittest.TestCase):
def test_1(self):
self.assertEqual(piotrSQL.round_my(1.53, -1), 1.5)
self.assertEqual(piotrSQL.round_my(1.55, -1), 1.6)
self.assertEqual(piotrSQL.round_my(1.63, -1), 1.6)
self.assertEqual(piotrSQL.round_my(1.65, -1), 1.7)
self.assertEqual(piotrSQL.round_my(1.53, -2), 1.53)
self.assertEqual(piotrSQL.round_my(1.53, -3), 1.53)
self.assertEqual(piotrSQL.round_my(1.53, 0), 2)
self.assertEqual(piotrSQL.round_my(1.53, 1), 0)
self.assertEqual(piotrSQL.round_my(15.3, 1), 20)
self.assertEqual(piotrSQL.round_my(157.3, 2), 200)
由于浮点数和小数之间转换的性质,并且量化似乎不适用于 10 或 100 之类的指数。有没有 Pythonic 方法可以做到这一点?
而且我知道我可以添加无限小的数字,round(num+10**(precission-20),-pricission) 会起作用,但这是错误的,以至于“小狗会死”...
【问题讨论】:
-
您知道例如
1.65不符合“四舍五入”的条件,因为它真的是1.649999999999999911182158029987...? -
我知道 - 这就是我写的原因:“因为浮点数和小数之间转换的性质” - 但你是对的,我应该更精确。另一方面,我现在想知道我可能应该省略浮点数并对十进制数执行所有计算......
-
不,这不是问题所在。问题是您根本没有
floats。无法恢复创建浮点数的字符串。在整个代码中将它们保留为字符串或小数,以避免“一个”陷阱 -
抱歉 - 在你提出你的回复之前,我已经编辑了我的回复......是的 - 你是对的......你的回答结束了这个问题。
标签: python floating-point decimal rounding