为什么我在这个Haskell程序中得到负数?

时间:2012-03-10 21:03:11

标签: math haskell functional-programming

我正在尝试创建一个计算二次公式的程序,但事实证明它总是给我一个负数而我找不到原因?

equation::(Double,Double,Double)->Double
equation(x,y,z)=(-y-sqrt(y^2+4*x*z))/(2*x) 

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:6)

您正在错误地实施二次方程式。方程中有一个平方根,平方根给出正数和负数(2*2-2*-2都得到4)。所以你想要这样的东西:

equation::(Double,Double,Double)->(Double,Double)
equation(x,y,z)=(((-1 * y + ( sqrt ( y^2 - (4 * x * z))))/(2 * x)),((-1 * y - ( sqrt ( y^2 - (4 * x * z))))/(2 * x)))

或者这个(之前的版本保留了您在原始样本中使用的格式,而此示例更清晰,更易于关注[imho])

quad :: (RealFloat a) => a -> a -> a -> (a,a)
quad x y z = 
        let a = ((-1 * y + ( sqrt ( y^2 - (4 * x * z))))/(2 * x))
            b = ((-1 * y - ( sqrt ( y^2 - (4 * x * z))))/(2 * x))
        in (a,b)

a是为平方根输出的数字,b是为平方根输出的数字。

答案 1 :(得分:2)

它并不总是给我一个负数:

Prelude> equation (-1) 4 1
3.732050807568877

正如人们可以得到的那样的Python:

>>> (-4 - math.sqrt(16 - 4))/-2
3.7320508075688772

如果你想要二次方程的根,你想要y^2 - 4*x*z,你需要加法而不是减法。

答案 2 :(得分:1)

由于您的定义在sqrt前面有一个减号,因此它总是会产生相关两个数字中较小的一个。这往往是消极的,但不一定如此:

Prelude> equation (2, -4, -2)
1.0

(我在学校学到的公式版本与4*x*z部分的符号略有不同,但这显然取决于要解决的等式是否为x*X^2 + y*X + z = 0形式或x*X^2 + y*X = z,所以我只是假设它不是拼写错误。)