如何修正乘法结果的错误小数位

时间:2019-06-03 18:42:58

标签: python string floating-point decimal

我在进行以下计算时遇到问题:

>>> print(float('32.31') * 1e9)
32310000000.000004

我需要此结果为32310000000.0(无错误的小数位)。直接使用浮点数时也会发生这种情况:

>>> print(32.31 * 1e9)
32310000000.000004

有没有办法避免小数点后的假位?分析字符串并四舍五入到小数点后的位数不是一个正确的解决方案。

非常感谢。

注意:以下工作正常:

>>> print(32.32 * 1e9)
32320000000.0

所以我很高兴在测试期间发现了上述问题。

编辑:感谢您的快速解答!抱歉,我错过了一个重点。该方法还必须适用于结果小于一的情况,例如:

32.31 * 1e-9

...在这种情况下,我不能使用round(32.31 * 1e-9, 1)

4 个答案:

答案 0 :(得分:2)

避免出现问题的一种方法是使用decimal模块,该模块以10为基数工作,因此可以像人类一样工作(如果我们快得多的话)。

from decimal import Decimal
value = float(Decimal('32.31') * Decimal(1e9))

这将产生您想要的值,

32310000000.0

另一种方法是使用fractions模块,该模块可以使用确切的值:

from fractions import Fraction
value = float(Fraction('32.31') * Fraction(1e9))

请注意,在这两种方法中,我们都必须转换1e9,而不仅仅是十进制值。使用1e9作为浮点数会将中间值转换为浮点数,并且再次弹出逼近问题。无论使用哪种方法,都可以不进行最终转换为浮点型的操作,而只需继续使用DecimalFraction值即可。这两种方法中的任何一种都比使用浮点类型要慢一些:您需要牺牲速度来获得准确性。在某些情况下,速度下降可能很重要。


关于您对问题的编辑:在我的任何一种方法中使用值1e-9仍会得到您想要的值,即值3.231e-08

答案 1 :(得分:0)

如果您只想用一个小数位打印,可以使用round,方法是指定要使用的小数点后的数字,在这种情况下为1

print(round(float('32.31') * 1e9, 1))
# 32310000000.0

答案 2 :(得分:0)

这是由浮点数的二进制尾数表示限制引起的。 32.31不能用除以2的幂表示。如果您知道自己的值将始终是整数(或已知的小数位数),则可以使用round()int(round())来规避该限制。

答案 3 :(得分:0)

我将假设您正在使用Python3。

如果只关心打印结果,请使用字符串格式:

print("{r:1.2f}".format(r=32.31 * 1e9))

另一种方法是使用较旧的格式语法:

print("%1.1f" % (32 * 1e9))

我更喜欢第一个,但是两个都可以。