![](/img/trans.png)
[英]Django: Multiplication of n Decimal Fields returns result with n*2 decimal places
[英]How to fix incorrect decimal places of a multiplication result
我的以下计算有问题:
>>> 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)
避免问题的一种方法是使用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
作为浮点数会将中间值转换为浮点数,并且再次弹出逼近问题。 无论使用哪种方法,都可以不进行最终转换为浮点型的操作,而仅继续使用Decimal
或Fraction
值即可。 这两种方法中的任何一种都比使用浮点类型要慢一些:您需要牺牲速度来获得准确性。 在某些情况下,速度降低可能很重要。
关于您对问题的编辑:在我的任何一种方法中使用值1e-9
仍然会得到所需的值,即值3.231e-08
。
如果您只想用一个小数位打印,可以通过指定要在小数点后的数字来使用round
入,在这种情况下为1
print(round(float('32.31') * 1e9, 1))
# 32310000000.0
这是由浮点数的二进制尾数表示限制引起的。 32.31不能用除以2的幂表示。 如果您知道您的值将始终是整数(或已知的小数位数),则可以使用round()
或int(round())
来规避该限制。
我假设您使用的是Python 3。
如果只关心打印结果,请使用字符串格式:
print("{r:1.2f}".format(r=32.31 * 1e9))
另一种方法是使用较旧的格式语法:
print("%1.1f" % (32 * 1e9))
我更喜欢第一个,但是任何一个都可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.