الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]ماذا يحصل فعلا عند التحويل من int الى long long int

بدأه Adam Sharafeddine في 18 أغسطس 2013 · 4 رد · 753 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

 

 

كنت اكتب شيفرة امنة لضرب عددين من نوع int و بحجم 4 بايت.

كما نعلم ان نتيجة الضرب قد تفوق حجم 4 بايتات.. كل البتات فوق ال32 بت سوف تحذف.

 

اذا رحت استعمل النوع long long int الذي هو بحجم 64 بت.

طبعا هذا النوع يستوعب جميع نتائج الضرب لعددين من نوع int.

 

و لكن احترت في الكود.

 

الكود الاول خاطىء:

int a, b;
//suppose that the multiplication of a and b gives a result that does not fit in 32bit type(int)
long long int c = a *b;

الكود خاطىء لان الفيض (overflow) سيحصل اولا عند الضرب.. ثم القيمة الغير صحيحة سوف يتم تحويلها الى long long int و تعيينها الى المتغيّر c.

 

 

الكود الثاني و هو الكود الصحيح:

int a, b;
//suppose that the multiplication of a and b gives a result that does not fit in 32bit type(int)
long long int c = (long long int) (a * b);

و لكن لا اعلم لماذا الكود الاخير هو الصحيح..

انا ارى انّ:

 

1)سوف يتم ضرب a  و b على اساس انهم 32 بت -> سوف نحصل على نتيجة فائضة (و خاطئة اذا)

2) ثم سوف يتم تحويل النتيجة الى 64 بت (الى long long int اعني) ثم سيتم تخزين النتيجة النهائية الى المتغيّر c.

 

 

اكيد فهمي خاطىء و اريد شرح كافي لتوضيح ماذا يحصل فعلا. و انا اظن ان المسالة لها علاقة بالAssociativity. يعني مثلا هل التحويل يتم اولا ام الضرب. و رغم ذلك لابد من توضيح.

1
#2

أنا لي بعض التلميحات السريعة:

اقتباس
ل التحويل يتم اولا ام الضرب

 

-الطبيعي الذي: نريدة ان يتم تحويل الارقام اولا الي 64 بت ثم تتم عملية الضرب، هنا نعمل فى حيز آمن من الذاكرة

 

عندما تقول:  (long long int) (a * b);  فانت هنا تجبر عملية الضرب علي ان تتم اولاً فى حيز 32 بت والنتجية انت تعلم انها اكبر من 32 وبالتالي يحدث طفح الفيض.

كان علينا ان نقول: (long long int) a * b; لكي يحجز حيز الذاكرة الآمن اولاً ثم تتم عملية الضرب.

تذكر قاعدة اولالوية تنفيذ المعاملات.

 

الكود بعد التعديل:

#include <stdio.h>

int main(void)
{
    int a=2000000000, b=2000000000;
    long long int c = (long long int)a*b;
    printf("%d\n", a);
    printf("%I64d\n", c);
    return 0;
}

المخرجات:

2000000000
4000000000000000000
Press <RETURN> to close this window...

مترجمي: Qt4.8.4 for Desktop - MinGW 4.4(Qt SDK)

تم تعديل هذه المشاركة بواسطة محمد عودة في 18 أغسطس 2013 في 13:10

2

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#3

إضافة على المشاركة الثانية.

 

الكود التالي:

(long long int) a * b

حيث انك قمت بشكل صريح بتحويل قيمة a للنوع long long int، حينها سيتم تحويل قيمة b بشكل ضمني للنوع long long int.

 

هذه العملية تخضع لـ integer promotion و تسمي بـ usual arithmetic conversions.

 

 

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة C++er في 18 أغسطس 2013 في 19:49

1

مدونتي: C++ Tips and Tricks

#4

شكرا لكم محمد و احمد.

تم تعديل هذه المشاركة بواسطة adam-master في 19 أغسطس 2013 في 00:05

#5

يا ريت لو تحط درس على الInteger Promotions في مدونتك :)

1

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…