2009-08-04 95 views
2

所以我完成了在haskell中創建自己的複數數據類型。Haskell浮點錯誤

我也得到了,因爲在這裏的另一個問題,得到了一個函數,將解決一個二次方程。

現在唯一的問題是,當試圖解決具有複雜根的二次方程時,代碼在擁抱中生成解析錯誤。

即在擁抱...

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) 
+0

你應該讓你的花車嚴格並且可能是雙倍的,即`!Double`。 – 2012-02-16 13:48:16

回答

7

你的數字似乎非規範化在錯誤:

 
(C -1.#IND -1.#IND) 

在這種情況下,你不能假設上漂浮的任何比較都是有效的了。這是浮點數的定義。然後你的顯示定義

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,然後在根,你倒下在你最後的情況下,並在第二個公式:

   y 
----------------------------- 
      ________________ 
     /  _______ 
     / /2 2 
     / x + \/ x + y 
2 * \/ ---------------- 
     \/   2 

-4 + sqrt((-4) ^2) == 0,從那裏,你註定的,除以0,接着是「南」(非數字),擰一切

+0

爲優秀的ASCII字根+1。 – 2009-08-04 16:33:53

1

關閉我的頭頂:它可能是您爲Complexshow定義的問題。

我注意到你沒有默認情況下是這樣的:

| otherwise = ... 

因此,如果有ri你的條件是不可窮盡的,你會得到一個pattern match failure

+0

擁抱似乎不喜歡關鍵字默認。無論如何,這不會是肯定的,因爲展會綜合體涵蓋所有案例。 – Thomas 2009-08-04 10:56:44

+0

啊,對不起,SuperBloup是正確的,否則``是關鍵字。 我編輯了我的回覆。 – dukedave 2009-08-04 13:28:23

4

戴夫擊中了頭部。

隨着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在告訴你哪裏出了問題方面顯然是勝利者。