المستوى: مبتدئ. المقال ده ليك لو لسه بتتعلّم البرمجة وصدمك إن رقم كبير لما تزود عليه 1 بيطلع سالب. هتفهم السبب من غير أي خلفية في الرياضيات المتقدمة.
ليه 2147483647 + 1 بيطلّع رقم سالب؟ شرح Integer Overflow للمبتدئ
لو كتبت سطر بيزود 1 على أكبر رقم صحيح، ولقيت الناتج رقم سالب ضخم زي 2147483648-، اطمئن: ده مش غلطة منك ولا bug في اللغة. ده سلوك متوقّع اسمه Integer Overflow (فيضان الأعداد الصحيحة). في آخر المقال هتعرف بالظبط ليه بيحصل، وإزاي تمنعه قبل ما يوقّعلك حسابات الفلوس أو عدّاد المشاهدات.
المشكلة باختصار
الكمبيوتر مش بيخزّن الأرقام في مساحة لا نهائية. كل رقم صحيح بياخد عدد ثابت من الخانات (bits). لما الرقم يكبر أكتر من المساحة دي، مفيش مكان يكمّل فيه، فبيلفّ من الأول — بالظبط زي عدّاد السيارة. النتيجة: رقم كبير جدًا فجأة بيبقى أصغر رقم سالب.
الفكرة بمثال: عدّاد السيارة
تخيّل عدّاد كيلومترات قديم فيه 6 خانات. أقصى رقم يقدر يوصله هو 999999. لو السيارة مشيت كيلومتر واحد زيادة، العدّاد مش هيكتب 1000000، لأن مفيش خانة سابعة. هيلفّ ويرجع 000000.
الكمبيوتر بيعمل نفس الحاجة بالظبط، بس بخانات ثنائية (0 و 1) مش عشرية. والفرق الوحيد إنه بيلفّ لرقم سالب مش للصفر، وهنشوف السبب دلوقتي.
المفهوم علميًا: البت، والثنائي، والمتمم الثنائي
الكمبيوتر بيخزّن كل حاجة كخانات ثنائية. النوع الأشهر للأعداد الصحيحة اسمه int32، وهو 32 خانة. واحدة من الـ 32 محجوزة لإشارة الرقم (موجب ولا سالب)، فبيتبقّى 31 خانة للقيمة نفسها.
عدد القيم اللي تقدر تتمثّل في 32 خانة هو 2 أس 32 = حوالي 4.29 مليار قيمة. بنقسمها نص للموجب ونص للسالب، فالمدى بيبقى من 2147483648- لحد 2147483647 (وهو 2 أس 31 ناقص 1).
طب ليه بيطلع سالب بالذات؟
الكمبيوتر بيمثّل الأرقام السالبة بطريقة اسمها المتمم الثنائي (Two's Complement). الخانة الأولى من الشمال بتشتغل كـ "إشارة": لو 0 الرقم موجب، لو 1 الرقم سالب.
أكبر رقم موجب 2147483647 كل خاناته 1 ما عدا خانة الإشارة (0). لما تزود عليه 1، الجمع بيكبّس على خانة الإشارة ويخليها 1، وكل باقي الخانات ترجع 0. القيمة دي في المتمم الثنائي معناها بالظبط 2147483648-. عشان كده الرقم مش بيرجع صفر زي العدّاد، بيقفز لأصغر رقم سالب.
كود شغّال يوريك الظاهرة
الكود ده Go وبيشتغل زي ما هو. جرّبه على Go Playground: