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)
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top