在我的情况下,我试图将一个浮动p
除以另一个q
。顶部是底部的倍数,两者都具有以下属性:
1
和1e-8
之间。(例如,p=.0014
和q=.00002
)
在一个完美的世界中,分裂会出现一个完美的整数(这里是70)。但浮点运算是often imperfect。
我希望使用最简单,最安全,最有效的方法来避免在将商转换为p/q - 1
时返回int
的错误。
我现在最好的解决办法是做这样的事情:
int(p/q + 1e-10)
但这可能是不可能的,并且可能效率低下。
此外,我知道我可以绕圈,但这似乎在代码中具有误导性,并且可能效率低于某种类型的直接演员。
答案 0 :(得分:2)
你如何处理这些问题,你所做的分工取决于你。也许您应该使用Decimal或Fraction对象,但在评估除法时,Python为此提供了一个模块:
>>> import fractions
>>> fractions.Fraction(.0014/.00002)
Fraction(70, 1)
>>> int(fractions.Fraction(2.3))
2
>>> int(fractions.Fraction(8.35))
8
但在仔细阅读了你的问题之后,我认为你的担忧是不合理的。如果你试图考虑一个分数,由于舍入误差,你将低于一个整数,如果你可以用更高的精度计算,你将在上面,你不能。
例如,下面给出的数字部分永远不会低于1:
>>> fractions.Fraction(1.000000000000001)
Fraction(4503599627370501, 4503599627370496)
在评论中,有人建议到达的股息不在1.64附近。他是如何达到这一点的,他没有说,但正如我在我的介绍中所说的那样,你如何计算分裂点取决于你。
答案 1 :(得分:2)
如果分子是分母的倍数并且商可以准确表示,则浮点除法将给出确切的答案。因此,将顶部分为底部是安全的,如果这是您正在尝试做的事情。
但是,您经常使用从十进制转换的数字,或者是某些计算的结果。在这些情况下,您需要弄清楚计算中可能出现多少错误(1.11e-16
的相对误差是从十进制转换的安全赌注,除非数字真的很小)并在转换之前将结果缩小到整数。
也就是说,当int((top / bot) * (1 + 2.22e-16))
和top
处于合理范围内时,bot
应该做你想做的事。
答案 2 :(得分:2)
从评论中的想法到问题,这是通过decimal:
的解决方案from decimal import Decimal
p = .0014
q = .00002
quotient = int(Decimal(str(p)) / Decimal(str(q)))
当然会产生70
。
请注意,通过字符串转换似乎是必要的,因为:
>>>print decimal.Decimal(8.4)
8.4000000000000003552713678800500929355621337890625
,而
>>>print decimal.Decimal(str(8.4))
8.4
答案 3 :(得分:0)
似乎到目前为止最直接的解决方案是舍入到int:
int(round(p/q))
或许还附有一条简短的评论,指出p
是q
的倍数,以避免p/q
与整数有潜在显着距离的任意暗示。
请注意,此解决方案保证完全安全,因为在这种情况下通过int()
进行投射会作用于round()
的{{3}}浮点数,由float
返回。根据用于Python decimal
符合的双精度的IEEE浮点标准,这种精确性可保证高达2 53 。
它可能在显微镜下效率低于其他方式(在问题中提出的建议),但肯定比通过fractions
或{{1}}模块处理更有效。并且可能与采用额外乘法和加法的其他解决方案相当。