الرئيسيةمن أناالدوراتالمدونةسوق الأوامرالمناهج والباقاتالشركاء

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • سوق الأوامر
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
البرمجة بالعربي

ليه العدّاد بيرجع رقم سالب فجأة؟ سر تجاوز الأعداد الصحيحة

مبتدئ9 أغسطس 20265 دقائق قراءة
ليه العدّاد بيرجع رقم سالب فجأة؟ سر تجاوز الأعداد الصحيحة
مستوى المقال: مبتدئ — مناسب لو لسه في بداية طريقك في البرمجة، ومفيش عندك خلفية عن طريقة تخزين الأرقام في ذاكرة الكمبيوتر. هنبدأ بمثال بسيط، وبعدين نرجع نشرح العلم اللي وراه بدقة.

بعد ما تخلّص المقال ده، هتعرف بالظبط ليه عدّاد بيوصل لـ 2,147,483,647 وفجأة يقلب لرقم سالب، وإزاي تمنع ده يحصل في قاعدة بياناتك أو كودك قبل ما يكسر شغلك.

ليه العدّاد بيرجع رقم سالب فجأة؟

المشكلة باختصار

لو عندك عمود بيعدّ حاجة — مشاهدات، طلبات، نقاط — وفجأة لقيت الرقم بقى بالسالب، أول رد فعل بيكون: "في باج في الكود". غالبًا لأ. ده سلوك متوقّع اسمه تجاوز الأعداد الصحيحة (Integer Overflow). بيحصل لما الرقم يتخطّى أكبر قيمة يقدر النوع يخزّنها، فيلفّ ويرجع من الأول. المشكلة مش في منطقك، دي حدود الذاكرة نفسها.

الحكاية بمثال بسيط: عدّاد السيارة

تخيّل عدّاد الكيلومترات الميكانيكي القديم في عربية. فيه 6 خانات، فبيعدّ من 000000 لحد 999999. لما توصل لآخر رقم وتمشي كيلومتر زيادة، الخانات كلها بتلفّ وترجع 000000. الرقم مرجعش صفر عشان العربية اتصلحت، رجع صفر لأن مفيش مكان لخانة سابعة.

الكمبيوتر بيعمل نفس الحاجة بالظبط. النوع الشائع اسمه int بعرض 32 بت. عنده عدد خانات ثابت، ولمّا يوصل لأكبر رقم ويزيد واحد، بيلفّ. الفرق الوحيد: عدّاد العربية بيرجع صفر، والكمبيوتر بيرجع لأصغر رقم سالب. هنعرف ليه دلوقتي.

طيب علميًا بيحصل إيه؟

النوع int32 بيتخزّن في 32 بت (خانة صفر أو واحد). أول بت من الشمال اسمه بت الإشارة (sign bit): لو صفر، الرقم موجب؛ لو واحد، الرقم سالب. الطريقة دي اسمها المتمّم الثنائي (Two's Complement)، وهي المعيار في كل المعالجات الحديثة.

أكبر رقم موجب بيبقى بت الإشارة صفر وباقي الـ 31 بت واحدات، يعني 2,147,483,647. أول ما تزيد واحد، بتّ الإشارة بيقلب لواحد، والباقي أصفار، فالنتيجة تبقى أصغر رقم: -2,147,483,648. مدى النوع كله من -2,147,483,648 لحد 2,147,483,647. الشريط ده بيوضّح لحظة الالتفاف بالظبط:

في الصورة استخدمنا نوع أصغر (8 بت) عشان يبان بسهولة: مداه من -128 لحد 127. أول ما تزيد على 127 بيرجع -128. نفس المبدأ بالظبط، بس بأرقام أصغر.

جرّبها بنفسك: كود بيوريك الانقلاب

الكود ده بلغة بايثون بيستخدم نوع ثابت العرض (int32) عشان يوريك الالتفاف الحقيقي:

Python
# لازم numpy عشان نوع ثابت العرض: pip install numpy
import numpy as np

x = np.int32(2_147_483_647)   # أكبر قيمة في int32
print(x + np.int32(1))        # النتيجة: -2147483648  ← انقلب سالب

# بايثون العادي مبيفيضش، بيكبّر الرقم لوحده:
y = 2_147_483_647
print(y + 1)                  # النتيجة: 2147483648  ← مفيش انقلاب

وفي جافاسكريبت، الأرقام أصلًا عائمة (float)، فبنجبرها على 32 بت بعلامة | 0 عشان نشوف نفس السلوك:

JavaScript
const max = 2147483647;
console.log((max + 1) | 0);   // -2147483648  ← الالتفاف

الافتراض هنا إنك بتستخدم نوع صحيح بعرض ثابت زي في C وC++ وJava وGo وعمود INTEGER في SQL. اللغات اللي أعدادها لا نهائية (بايثون، روبي) مبتقعش في المشكلة دي على مستوى المتغير العادي.

حصلت في الحقيقة (بأرقام)

ده مش كلام نظري. في ديسمبر 2014 فيديو "Gangnam Style" على يوتيوب عدّى 2,147,483,647 مشاهدة، وهو بالظبط سقف الـ 32 بت. يوتيوب اضطروا ينقلوا العدّاد لـ 64 بت، اللي سقفه 9,223,372,036,854,775,807 (حوالي 9.2 كوينتيليون مشاهدة).

وأخطر من كده: طائرة بوينج 787. لو فضلت شغّالة من غير إعادة تشغيل مدة 248 يوم، عدّاد داخلي في وحدة التحكم في المولّد بيفيض ويطفّي كل الكهرباء المتردّدة. الرقم ده مش صدفة: 248 يوم بالظبط تساوي 2³¹ من أجزاء المئة من الثانية. الحل المؤقت اللي فرضته هيئة الطيران الأمريكية كان: أعد تشغيل الطائرة دوريًا.

وفيه قنبلة موقوتة اسمها مشكلة سنة 2038: كتير من الأنظمة بتخزّن الوقت كعدد ثوانٍ من 1970 في نوع int32. العدّاد ده هيفيض يوم 19 يناير 2038، فأي نظام لسه شغّال بالطريقة دي ممكن يتصرف كإن الوقت رجع لـ 1901.

الحل والـ trade-off

أفضل طريقة عملية: استخدم نوع 64 بت (BIGINT في قواعد البيانات، أو int64/long في الكود) لأي عدّاد ممكن يكبر. بتكسب مدى ضخم عمليًا ملوش سقف في شغلك اليومي. بتخسر ضعف التخزين: 8 بايت بدل 4 لكل قيمة. على معالجات وقواعد بيانات النهارده الفرق ده تافه في 99% من الحالات.

بديل تاني: النوع غير المؤشّر (unsigned) بيوصل لـ 4,294,967,295، يعني بيضاعف المدى الموجب، بس بتخسر القدرة على تخزين أرقام سالبة. مناسب لو متأكد إن القيمة مستحيل تبقى سالبة (زي عدّاد).

متى لا تشغل بالك

لو القيمة صغيرة ومحدودة ومعروفة (عمر شخص، عدد عناصر في قائمة قصيرة)، النوع 32 بت أكتر من كافي وملوش أي داعي تعقّد حياتك. وكمان لو شغّال بلغة بأعداد لا نهائية زي بايثون وروبي على مستوى المتغيرات العادية. بس انتبه في لحظتين: أول ما تكتب في عمود قاعدة بيانات نوعه INT، وأول ما تتعامل مع وقت (timestamp) بنظام 32 بت.

الخطوة التالية

افتح قاعدة بياناتك دلوقتي، ودوّر على أي عمود بيعدّ حاجة بتكبر مع الوقت (views، counter، أي id تسلسلي). لو نوعه INT بـ 32 بت وممكن نظريًا يعدّي 2.1 مليار، غيّره لـ BIGINT قبل ما يلفّ ويرجع سالب في الإنتاج. التغيير رخيص دلوقتي، وغالي جدًا بعد ما يحصل.

المصادر

  • حادثة يوتيوب: TechCrunch — Gangnam Style broke YouTube's counter وBBC News.
  • تحليل تقني للانقلاب: Exploring Binary.
  • حادثة بوينج 787: Engadget وI-Programmer والأمر الرسمي من وزارة النقل الأمريكية (FAA AD).
  • مشكلة سنة 2038: Year 2038 problem — Wikipedia.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة