0

我对python很陌生,正在尝试编写一些代码来解决给定的二次函数。我在浮点数的舍入误差方面遇到了一些麻烦,我想是因为我将两个非常大但差异非常小的数字相除。(另外我假设所有输入现在都有真正的解决方案。)我已经放置了两个不同版本的二次方程来说明我的问题。它适用于大多数输入,但是当我尝试a = .001,时b = 1000c = .001我得到两个有显着差异的答案。这是我的代码:

from math import sqrt

a = float(input("Enter a: "))
b = float(input("Enter b: "))
c = float(input("Enter c: "))

xp = (-b+sqrt(b**2-4*a*c))/(2*a)
xn = (-b-sqrt(b**2-4*a*c))/(2*a)

print("The solutions are: x = ",xn,", ",xp,sep = '')

xp = (2*c)/(-b-sqrt(b**2-4*a*c))
xn = (2*c)/(-b+sqrt(b**2-4*a*c))

print("The solutions are: x = ",xn,", ",xp,sep = '')
4

5 回答 5

1

我不是数学领域的专家,但我相信你应该使用 numpy(数学的 py 模块),由于计算机上的内部数字表示,你的微积分与真正的数学不匹配。(浮点运算)

http://docs.python.org/2/tutorial/floatingpoint.html

检查这几乎是你想要的。

http://www.annigeri.in/2012/02/python-class-for-quadratic-equations.html

于 2012-12-28T17:00:37.007 回答
1

要使用浮点获得更精确的结果,请注意不要减去相似的数量。对于二次方程x^2 + a x + b = 0,你知道根x1x2使

b = x1 * x2

计算绝对值较大的一个,并从这个关系中得到另一个。

于 2012-12-28T17:06:38.603 回答
0

解决方案:

用户 dhunter 建议的Numpy通常是 Python 中数学的最佳解决方案。numpy 库能够在许多不同领域进行快速准确的数学运算。

python 2.4 中添加了十进制数据类型 只需添加:

from decimal import *

到代码的顶部,然后用单词 Decimal 替换单词 float 的所有实例(注意大写的“D”。)

例如:Decimal(1.1047262519)相对于float(1.1047262519)

理论:

浮点运算基于二进制数学,因此并不总是用户所期望的。对浮动 Vs 的出色描述。十进制类型位于此处

于 2012-12-28T17:25:34.480 回答
0

您应该处理以下特殊情况:

  1. a == 0 表示一个线性方程和一个根:x = -c/b
  2. b == 0 表示 x1, x2 = ±sqrt(-c/a) 形式的两个根
  3. c == 0 表示两个根,但其中一个是零:x*(ax+b) = 0
  4. 如果判别式为负,则有两个复共轭根。

我建议以这种方式计算判别式:

discriminant = b*sqrt(1.0-4.0*a*c/b)

我还建议阅读以下内容:

https://math.stackexchange.com/questions/187242/quadratic-equation-error

于 2012-12-28T17:53:47.237 回答
0

前面提到的numpy模块与问题中提到的舍入误差并不是特别相关。另一方面,可以以蛮力方式使用小数模块来获得准确的计算。以下来自 ipython 解释器会话的片段说明了它的用法(默认为 28 位精度),并且还显示了相应的浮点计算只有 5 个小数位的精度。

In [180]: from decimal import Decimal
In [181]: a=Decimal('0.001'); b=Decimal('1000'); c=Decimal('0.001')
In [182]: (b*b - 4*a*c).sqrt()
Out[182]: Decimal('999.9999999979999999999980000')
In [183]: b-(b*b - 4*a*c).sqrt()
Out[183]: Decimal('2.0000000000020000E-9')
In [184]: a = .001; b = 1000; c = .001
In [185]: math.sqrt(b*b - 4*a*c)
Out[185]: 999.999999998
In [186]: b-math.sqrt(b*b - 4*a*c)
Out[186]: 1.999978849198669e-09
In [187]: 2*a*c/b
Out[187]: 1.9999999999999997e-09

4ac与 相比,平方根的泰勒级数b**2提供了另一种使用方法。在这种情况下,√(b*b-4*a*c) ≈ b - 4*a*c/(2*b),从哪里来b - √(b*b-4*a*c) ≈ 2*a*c/b。从上面的行 [187] 条目中可以看出,泰勒级数计算在使用浮点而不是小数时给出了 12 位精确的结果。使用另一个泰勒级数项可能会增加几位数的准确性。

于 2012-12-28T17:58:49.547 回答