ج :إخراج خاطئ لـ "(طويل طويل int) = (طويل طويل int) * (مزدوج)"؟

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

سؤال

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);

long long int out = A + B*D;

printf("%lld",out);

هذا يعطي النتيجة:-2147483648

لا أستطيع معرفة السبب (ينبغي أن تكون نتيجة إيجابية).هل يمكن لأحد أن يساعد؟

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

المحلول

وتخميني هو أن المترجم يحتاج إلى جولة النتيجة من "A + B * D" إلى عدد صحيح أولا، لأنك تخزين النتيجة داخل حقل كثافة العمليات. ذلك أساسا، كنت تواجه صراعا نوع البيانات.

وكلا A و B لا تزال أرقام صالحة لكثافة طويل، والذي هو 8 بايت. حتى انك تستطيع مضاعفة لهم من قبل 1.000 والتي لا تزال القيم كثافة العمليات طويلة طويلة صالحة. في بعض اللغات الأخرى ومن المعروف أيضا باسم int64.

وهناك ضعف، ولكن، أيضا 64 بت ولكن يتم استخدام جزء من تلك كما الأس. عند ضربها مزدوج مع int64، فإن النتيجة ستكون آخر مزدوجة. مضيفا int64 آخر لأنه لا يزال يحافظ عليه مزدوجة. ثم كنت تعيين نتيجة لint64 مرة أخرى دون استخدام طريقة التقريب معين. فإنه لن يفاجئني إذا كان المترجم سوف تستخدم وظيفة التقريب 4 بت لهذا الغرض. أنا حتى عن دهشتها أن المترجم لا تقيؤ وكسر على هذا البيان!

وعلى أي حال، عند استخدام أعداد كبيرة مثل هذه، عليك أن تكون حذرا عند خلط أنواع مختلفة.

نصائح أخرى

وربما لديك لتحديد هذه الثوابت كما الحرفية "طويلة المدى"؟ مثلا 3289168178315264LL

وماذا مترجم / نظام التشغيل الذي تستخدمه؟ ركضت التعليمات البرمجية باستخدام Visual C ++ 2008 اكسبرس الطبعة على نظام التشغيل Windows XP ويعمل IT - الجواب: 6578336356630528 (هذا هو رقم 53 بت، لذلك يناسب فقط داخل مزدوج)

وكما أنني حاولت شكلان لمعرفة ما إذا كان يهم ترتيب العمليات:

وكثافة العمليات طويلة طويلة خارج = A؛ من + = B * D؛

وكثافة العمليات طويلة طويلة خارج = B * D. من + = A؛

وهذه على حد سواء العمل كذلك!

والغريب.

وإجابتك (يجب أن تحقق) calcuates بنجاح، ومع ذلك، فإنه يتسبب حدث تجاوز في بت تسجيل، الأمر الذي يجعل الجواب سلبي. الحل: جعل كل المتغيرات الخاصة بك غير الموقعة

لماذا:

يتم تخزين

وأرقام عن سلسلة من البتات في الذاكرة لجهاز الكمبيوتر. بت الأول في مثل هذه السلسلة، عندما مجموعة يعني أنك الرقم سالبا. لذلك يعمل حساب، ولكن تجاوزات في بت تسجيل.

والتوصيات:

إذا كنت تعمل مع الأرقام الكبيرة هذه، فإنني أوصي لكم للحصول على مكتبة multiprecision حسابي. 'T سيوفر لك الكثير من الوقت والمتاعب.

يجب أن تكون المعلمة إلى sqrt مزدوج.

#include <math.h>
double sqrt( double num );

وأيضاً يجب أن نوضح النتيجة من B * D إلى long long.

    long long int A = 3289168178315264;
    long long int B = 1470960727228416;
    double D = sqrt(5.0);
    printf("%f\n",D);
    long long int out = A + (long long) (B * D);
    printf("%lld",out);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top