Haskell浮動小数点エラー
-
22-07-2019 - |
質問
だから私はhaskellで独自の複素数データ型の作成を終えました。
また、ここでの別の質問のおかげで、二次方程式を解く関数を手に入れました。
唯一の問題は、複雑な根を持つ2次方程式を解こうとすると、コードがハグで解析エラーを生成することです。
i.e。抱擁で...
Main> solve (Q 1 2 1)
(-1.0,-1.0)
Main> solve (Q 1 2 0)
(0.0,-2.0)
Main> solve (Q 1 2 2)
(
Program error: pattern match failure: v1618_v1655 (C -1.#IND -1.#IND)
平方根が適用された後の問題は、私のように見えますが、実際にはわかりません。何が間違っているのか、このエラーが何を意味するのかの兆候を拾おうとする助けは素晴らしいでしょう。
ありがとう、
トーマス
コード:
-- A complex number z = (re +im.i) is represented as a pair of Floats
data Complex = C {
re :: Float,
im :: Float
} deriving Eq
-- Display complex numbers in the normal way
instance Show Complex where
show (C r i)
| i == 0 = show r
| r == 0 = show i++"i"
| r < 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r < 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| r > 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r > 0 && i > 0 = show r ++ " + "++ show (C 0 i)
-- Define algebraic operations on complex numbers
instance Num Complex where
fromInteger n = C (fromInteger n) 0 -- tech reasons
(C a b) + (C x y) = C (a+x) (b+y)
(C a b) * (C x y) = C (a*x - b*y) (b*x + b*y)
negate (C a b) = C (-a) (-b)
instance Fractional Complex where
fromRational r = C (fromRational r) 0 -- tech reasons
recip (C a b) = C (a/((a^2)+(b^2))) (b/((a^2)+(b^2)))
root :: Complex -> Complex
root (C x y)
| y == 0 && x == 0 = C 0 0
| y == 0 && x > 0 = C (sqrt ( ( x + sqrt ( (x^2) + 0 ) ) / 2 ) ) 0
| otherwise = C (sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ((y/(2*(sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ) ) )
-- quadratic polynomial : a.x^2 + b.x + c
data Quad = Q {
aCoeff, bCoeff, cCoeff :: Complex
} deriving Eq
instance Show Quad where
show (Q a b c) = show a ++ "x^2 + " ++ show b ++ "x + " ++ show c
solve :: Quad -> (Complex, Complex)
solve (Q a b c) = ( sol (+), sol (-) )
where sol op = (op (negate b) $ root $ b*b - 4*a*c) / (2 * a)
解決
あなたの番号はエラーで非正規化されているようです:
(C -1.#IND -1.#IND)
この場合、floatの比較がもう有効であると仮定することはできません。これは、浮動小数点数の定義にあります。次に、ショーの定義
show (C r i)
| i == 0 = show r
| r == 0 = show i++"i"
| r < 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r < 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| r > 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r > 0 && i > 0 = show r ++ " + "++ show (C 0 i)
非正規化された数値のため、パターン障害の機会を残します。次の条件を追加できます
| otherwise = show r ++ "i" ++ show i"
今、なぜそうなのか、あなたが評価するとき
b * b - 4 * a * c
Q 1 2 2を使用すると、-4が得られ、ルートで最後のケースに該当し、2番目の式になります:
y
-----------------------------
________________
/ _______
/ / 2 2
/ x + \/ x + y
2 * \ / ----------------
\/ 2
-4 + sqrt((-4)^ 2)== 0
、そこから、あなたは運命にあり、0で除算し、その後に「NaN」が続きます; (数字ではない)、他のすべてをねじ込む
他のヒント
デイブは頭の爪を打ちました。
GHCiの元のコードでは、次のようになります。
*Main> solve (Q 1 2 2) (*** Exception: c.hs:(11,4)-(17,63): Non-exhaustive patterns in function show
ショーブロックを更新する場合:
instance Show Complex where
show (C r i)
| i == 0 = show r
| r == 0 = show i++"i"
| r < 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r < 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| r > 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r > 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| otherwise = "???(" ++ show r ++ " " ++ show i ++ ")"
その後、GHCiでこの情報を取得します。
*Main> :l c.hs [1 of 1] Compiling Main ( c.hs, interpreted ) c.hs:22:0: Warning: No explicit method nor default method for `abs' In the instance declaration for `Num Complex' c.hs:22:0: Warning: No explicit method nor default method for `signum' In the instance declaration for `Num Complex' Ok, modules loaded: Main. *Main> solve (Q 1 2 2) (???(NaN NaN),???(NaN NaN))
「生まれ育った」私GHCiでは、Hugsが警告とエラーの冗長性をどのように比較するかを正確に知りません。しかし、GHCiが何が悪かったのかを明確に伝えているようです。
私の頭上: Complex
の show
の定義に問題がある可能性があります。
次のようなデフォルトのケースがないことに気付きました:
| otherwise = ...
したがって、 r
および i
の条件が完全ではない場合、 pattern match failure
が発生します。