ما هو خوارزمية جيدة لتحديد ما إذا كان الإدخال هو الكمال مربع ؟ [مكررة]

StackOverflow https://stackoverflow.com/questions/343852

  •  19-08-2019
  •  | 
  •  

سؤال

ممكن مكررة:
أسرع طريقة لتحديد ما إذا كان عدد صحيح هو الجذر التربيعي هو عدد صحيح

ما هي الطريقة لمعرفة ما إذا كان الرقم هو الكمال مربع?

bool IsPerfectSquare(long input)
{
   // TODO
}

أنا باستخدام C# ولكن هذه هي اللغة الملحد.

نقاط المكافأة الوضوح والبساطة (هذا ليس من المفترض أن يكون رمز-جولف).


تحرير: هذا أكثر تعقيدا بكثير مما كنت أتوقع!اتضح المشاكل مع الدقة المزدوجة تعبر عن نفسها عدة طرق.الأول, الرياضيات.الجذر التربيعي يأخذ مزدوجة التي لا يمكن على وجه التحديد عقد طويل (بفضل جون).

ثانيا مزدوجة الدقة سوف تفقد القيم الصغيرة ( .000...00001) عندما يكون لديك ضخمة بالقرب من الكمال مربع.مثل تنفيذ بلدي فشل هذا اختبار الرياضيات.الأسرى(10,18)+1 (الألغام ذكرت صحيح).

هل كانت مفيدة؟

المحلول

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

هذا قد تفلت من بعض من مشاكل فحص فقط "هو جذر تربيعي عدد صحيح" ولكن ربما ليس كل شيء.هل يحتمل أن تحتاج إلى الحصول على القليل funkier:

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;
}

رديء و غير الضرورية لأي شيء عدا حقا قيم كبيرة ، ولكن أعتقد أنه يجب أن العمل...

نصائح أخرى

bool IsPerfectSquare(long input)
{
    long SquareRoot = (long) Math.Sqrt(input);
    return ((SquareRoot * SquareRoot) == input);
}

في Common Lisp, يمكنني استخدام التالية:

(defun perfect-square-p (n)
  (= (expt (isqrt n) 2)
     n))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top