it-swarm.com.de

Was ist ein guter Algorithmus, um festzustellen, ob eine Eingabe ein perfektes Quadrat ist?

Mögliches Duplikat:
Schnellste Methode, um festzustellen, ob die Quadratwurzel einer Ganzzahl eine Ganzzahl ist

Wie kann man sehen, ob eine Zahl ein perfektes Quadrat ist?

bool IsPerfectSquare(long input)
{
   // TODO
}

Ich verwende C #, aber das ist sprachunabhängig.

Bonuspunkte für Klarheit und Einfachheit (dies ist kein Code-Golf).


Edit: Das wurde viel komplexer als ich erwartet hatte! Es stellt sich heraus, dass sich die Probleme mit doppelter Präzision auf verschiedene Arten manifestieren. Erstens nimmt Math.Sqrt ein Double, das nicht lange halten kann (danke Jon).

Zweitens verliert die Genauigkeit eines Doppels kleine Werte (.000 ... 00001), wenn Sie ein großes, nahezu perfektes Quadrat haben. Meine Implementierung hat diesen Test für Math.Pow (10,18) +1 nicht bestanden (meiner hat sich als wahr erwiesen).

83
Michael Haren
bool IsPerfectSquare(long input)
{
    long closestRoot = (long) Math.Sqrt(input);
    return input == closestRoot * closestRoot;
}

Dies kann von einigen der Probleme, nur zu überprüfen, "ist die Quadratwurzel eine ganze Zahl", aber möglicherweise nicht alle. Möglicherweise müssen Sie ein bisschen funkiger werden:

bool IsPerfectSquare(long input)
{
    double root = Math.Sqrt(input);

    long rootBits = BitConverter.DoubleToInt64Bits(root);
    long lowerBound = (long) BitConverter.Int64BitsToDouble(rootBits-1);
    long upperBound = (long) BitConverter.Int64BitsToDouble(rootBits+1);

    for (long candidate = lowerBound; candidate <= upperBound; candidate++)
    {
         if (candidate * candidate == input)
         {
             return true;
         }
    }
    return false;
}

Icky und unnötig für alles andere als wirklich große Werte, aber ich denke es sollte funktionieren ...

116
Jon Skeet
bool IsPerfectSquare(long input)
{
    long SquareRoot = (long) Math.Sqrt(input);
    return ((SquareRoot * SquareRoot) == input);
}
12
Treb

In Common LISP verwende ich Folgendes:

(defun perfect-square-p (n)
  (= (expt (isqrt n) 2)
     n))
9
Svante