Haskell二次方程函数返回(NaN, NaN)的原因排查求助
二次方程函数返回NaN的原因及解决思路
你的Haskell函数返回(NaN, NaN),核心原因有两个:
- 判别式为负数:代码中
s = sqrt (b*b - 4.0*a*c)这一行,当根号内的判别式b²-4ac < 0时,sqrt函数对负数开平方会返回NaN——因为Float类型只支持实数运算,不处理复数结果。 - 参数a为0:如果传入的a是0,原方程就不是二次方程了,此时
d = 2.0*a等于0,后续的除法运算(-b ± s)/0会产生NaN(若此时判别式也为负,结果就全是NaN)。
改进后的示例代码
可以增加参数校验和错误提示,避免直接返回无意义的NaN:
roots :: (Float, Float, Float) -> Either String (Float, Float) roots (0, _, _) = Left "参数a不能为0,这不是二次方程" roots (a,b,c) = let discriminant = b*b - 4.0*a*c in if discriminant < 0 then Left "判别式为负,无实数根" else let s = sqrt discriminant d = 2.0*a in Right ((-b + s)/d, (-b - s)/d)
这个版本用Either类型明确返回错误信息或有效根,调试和使用起来更清晰。
内容的提问来源于stack exchange,提问作者Loren Beer
相关产品推荐
相关产品推荐

