سؤال
أواجه مشكلة في C#. لتكون دقيقة مع Math.Pow (). إذا حاولت حساب 15^14 ، فأنا أحصل على "29192926025390624". ولكن إذا قمت بحسابها باستخدام Wolfram Alpha ، أحصل على "29192926025390625". كما ترون هذا الاختلاف الوحيد هو رقم واحد. Wolfram Alpha صحيح رغم ذلك. لماذا لا C#؟ وكيف يمكنني إصلاح هذا حتى أتمكن من الحصول على القيمة الصحيحة في C#؟ 7
الكود الخاص بي بسيط إلى حد ما لأنني أحاول فقط مع أمثلة متشددين. إذن ما أفعله هو: Math.Pow(15,14);
هذا يعطي 29192926025390624
. وليس "29192926025390625" وهو الإجابة الصحيحة.
الروابط: ولفرام ألفا
المحلول
Math.Pow
تعمل على أنواع النقاط العائمة ، والتي هي حسب التعريف غير دقيق. إذا كنت بحاجة إلى أعداد صحيحة دقة تعسفية ، فاستخدم نوعًا صحيحًا للدقة التعسفية مثل Biginteger بنية. BigInteger لديه أيضا أسير الحرب طريقة.
نصائح أخرى
الرياضيات يعمل على الزوجي. هذا التنفيذ مع لونغ يحصل على الإجابة الصحيحة:
Func<long, int, long> power = null;
power = (i, p) => p == 1 ? i : i*power(i, p - 1);
Console.WriteLine(power(15, 14));
الرياضيات يعمل على الزوجي. الزوجي 64 بت نقطة عائمة ولديها حوالي 15-16 رقمًا من الدقة في C#, ، وبالتالي ، ما تراه هو خطأ تقريب. هذه هي الطريقة التي تعمل بها أرقام النقاط العائمة.
إذا كنت بحاجة إلى مزيد من الدقة ، فحاول استخدامها عدد عشري. إنه 128 بت ويستخدم 10 كقاعدة. هذا يمنحك تمثيلًا دقيقًا للأرقام التي تصل إلى 28-29 رقماً مهمًا. يمكنك بسهولة تحديد طريقة POW الخاصة بك للعشرية.
إذا decimal
لا يكفي ، انتقل إلى Biginteger, التي تمت إضافتها في .NET 4.
تعمل Math.Pow () بشكل صحيح مشكلتها مع نوع البيانات المزدوجة انظر الى هذا.
double i = 29192926025390625;
Console.WriteLine("{0}",i);//the result will be 29192926025390624.0
عفوًا آسف ، تحقق من القيمة حسب نقطة الإيقاف ؛ في برنامجك ؛
C #'s Math.Pow إرجاع مزدوج ، رقم نقطة عائم قياسية IEEE 754. لديها فقط 15 رقمًا مهمًا:
http://msdn.microsoft.com/en-us/library/system.math.pow.aspxhttp://math.byu.edu/~schow/work/ieeefloatingpoint.htm