python: how accurate math.sqrt(x) function is?
在Python中考虑以下代码片段:
对于n = 25,它应该给m = 5(并且在我的shell中确实如此)。但是从我的C经验中,我知道使用这样的表达式是一个坏主意,因为sqrt函数的返回值可能会比实际值稍低,然后在四舍五入后,我可能会得到m = 4而不是m = 5。参与python吗?如果是这种情况,用python编写此类表达式的最佳方法是什么?如果我使用Java或C#,会发生什么?
此外,如果有任何不准确之处,哪些因素控制着它的数量?
- 您确定多数民众赞成在python代码段?看来您正在尝试类型转换,您可能应该这样写:m = int(math.sqrt(n)),它与您编写的内容等效,但仅是因为(int)-> int,然后使用在语句的下一部分加上括号。
-
由于我们无法控制math.sqrt,因此您唯一可以做的就是编写自己的math.sqrt实现或编写自己的强制转换为integer的实现。
-
@JeffTratner抱歉。.我是python的新手。我写的就像我在C中所做的一样。我正在纠正它。
-
查找有关浮动精度的任何问题。任何问题,因为这些问题完全与语言无关,并且与sqrt无关。
为正确舍入,请使用round();四舍五入到最接近的整数,但返回一个浮点数。然后您可以根据结果构造一个int。
(很可能您的代码不是性能至关重要的对象,并且您永远不会注意到与round()相关的任何速度下降。如果这样做,您可能仍然应该使用numpy。)
-
请注意,round(以及floor,ceil和trunc)给出了来自Py3的整数。
如果您非常关心sqrt的准确性,则可以使用标准库中的decimal.Decimal类,该类提供了自己的sqrt函数。可以将Decimal类设置为比常规Python float更高的精度。也就是说,无论如何,四舍五入都可能无关紧要。 Decimal类产生精确的数字(来自文档):
The exactness [of Decimal] carries over into arithmetic. In decimal floating point,
0.1 + 0.1 + 0.1 - 0.3 is exactly equal to zero. In binary floating point, the result is 5.5511151231257827e-017. While near to zero, the
differences prevent reliable equality testing and differences can
accumulate. For this reason, decimal is preferred in accounting
applications which have strict equality invariants.
-
所有的解决方案都不错,但是Im标记是可以接受的,因为它指出了克服python中浮点错误的通用方法。
-
decimal也是浮点数,因此也不精确。仅对于以有理数为底的数字是精确的,这些数字在基数10中的显示最多需要当前上下文所允许的精度。当您需要更高的精度时,它是不精确的(可以做到),并且每当输入无理数时,它都不是精确的。尝试使用小数sqrt(2)**2(扰流器:默认精度不是2)。首选十进制浮点数的唯一原因是某些应用程序(例如财务)已经执行相同的截断操作的时间长于计算机的存在时间。
-
实际上,我的意思是在这种情况下,当我无法真正提供4.999999995或5.00000002时,它可以提供准确性:)
-
@Rafi没错,它会给你4.999999999999999999999999999999995。 :)
-
@Rafi在python帮助中:"十进制浮点数具有任意大范围的有限精度。此模块的目的是使用熟悉的校舍规则支持算术运算,并避免一些与二进制浮点数相关的棘手的表示问题。"我认为主要的优势是用户可定义的精度和范围。
-
十进制对于财务计算非常有用。对于科学/物理,更不用说了。
解决方案很简单。如果期望整数结果,请使用int(math.sqrt(n).1)。如果该值大于或小于整数结果,它将四舍五入为正确的值。
- @warwaruk糟糕,很抱歉错过了.1中的点。是的,这可能有效。
-
@delnan:根本不是黑客,承认浮点数学是不准确的并且适当地补偿是数值方法的关键。如果不这样做,那么阈值问题将接近理论值。这段代码只是说我们期望结果是正确的/ 1.。
-
我不是说它不起作用,并且完全知道它为什么起作用。我说这是对浮点值不准确的一种不太好的解决方法(并且可能会失败-对于非常大的值-尽管没什么大不了),而Id则希望使用更优雅的解决方案-例如不使用浮点数需要比其提供的精度更高的上下文。