Haskell Floating- Point-Fehler
-
22-07-2019 - |
Frage
So habe ich beenden meinen eigenen komplexen Zahl Datentyp in Haskell zu schaffen.
Ich habe auch dank einer anderen Frage hier, hätte eine Funktion, die eine quadratische Gleichung lösen.
Das einzige Problem ist jetzt, dass der Code einen Analysefehler in Umarmungen erzeugt, wenn ein quadratischen mit komplexen Wurzeln zu lösen versuchen.
d. In Umarmungen ...
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)
Es sieht aus meinem wie sein einem Problem nach der Quadratwurzel angewandt wurde, aber ich bin wirklich nicht sicher. Jede Hilfe versuchen zu holen, was nicht in Ordnung ist oder irgendwelche Hinweise darauf, was diese Fehler Mittel wären brillant.
Danke,
Thomas
Der Code:
-- 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)
Lösung
Ihre Zahlen scheint in Ihrem Fehler denormalized:
(C -1.#IND -1.#IND)
In diesem Fall kann man nicht davon ausgehen, dass ein Vergleich auf Schwimmer ist mehr gültig. Dies ist in der Definition von Gleitkommazahlen. Dann ist Ihre Definition von Show
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)
Urlaub Gelegenheit für einen Musterfehler, wegen denormalized Zahlen. Sie können die folgende Bedingung hinzufügen
| otherwise = show r ++ "i" ++ show i"
Jetzt für die, warum ist es so, dass, wenn Sie die Bewertung
b * b - 4 * a * c
mit Q 1 2 2, erhalten Sie -4, und dann in Wurzel, fallen Sie in Ihrem letzten Fall, und in der zweiten Gleichung:
y
-----------------------------
________________
/ _______
/ / 2 2
/ x + \/ x + y
2 * \ / ----------------
\/ 2
-4 + sqrt( (-4) ^2) == 0
, von dort, Sie sind verloren, Division durch 0, gefolgt von einem "NaN" (keine Zahl), Schrauben alles andere
Andere Tipps
Dave traf den Nagel auf den Kopf.
Mit dem ursprünglichen Code in GHCi, erhalte ich:
*Main> solve (Q 1 2 2) (*** Exception: c.hs:(11,4)-(17,63): Non-exhaustive patterns in function show
Wenn wir den Show-Block aktualisieren:
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 ++ ")"
dann erhalten wir diese Informationen in 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))
Ich war „geboren und aufgewachsen“ auf GHCi, so dass ich weiß nicht genau, wie Umarmungen in Ausführlichkeit der Warnungen und Fehler vergleichen; aber es sieht aus wie GHCi ein klarer Sieger ist Sie sagen, was falsch gelaufen ist.
Aus der Spitze von meinem Kopf: Es könnte ein Problem mit der Definition von show
für Complex
sein.
Ich stelle fest, Sie nicht Standard-Fall wie folgt aussehen:
| otherwise = ...
Deshalb, wenn Ihre Bedingungen mit r
und i
nicht erschöpfend sind es eine pattern match failure
erhalten.