خطأ بمقدار واحد

خطأ الاختلاف بمقدار واحد ( المعروف اختصارًا بـ OBOE و OBOB و OBO و OB1 ) هو خطأ منطقي يتضمن عددًا يختلف عن قيمته المقصودة بمقدار واحد. قد يظهر هذا الخطأ أحيانًا في سياق رياضي ، كما أنه شائع في برمجة الحاسوب عندما تتكرر حلقة تكرارية مرة واحدة أكثر أو أقل من اللازم، وعادةً ما يكون السبب هو استخدام متباينة غير صارمة (≤) كشرط إنهاء بينما كان ينبغي استخدام متباينة صارمة (<)، أو العكس. ينشأ خطأ الاختلاف بمقدار واحد أيضًا من سوء فهم الترقيم الذي يبدأ من الصفر .

حالات

خطأ في عمود السياج

خطأ عمود السياج ( ويُسمى أحيانًا خطأ عمود التلغراف أو عمود الإنارة أو خطأ السياج الخشبي ) هو نوع محدد من أخطاء القياس بمقدار واحد. وقد ورد وصف مبكر لهذا الخطأ في مؤلفات فيتروفيوس . [ 1 ] وتوضح المسألة التالية هذا الخطأ:

إذا قمت ببناء سياج مستقيم بطول 30 قدمًا مع أعمدة متباعدة بمقدار 3 أقدام، فكم عدد الأعمدة التي تحتاجها؟

يتطلب السياج المستقيم المكون من 10 أقسام 11 عمودًا. وبشكل عام، يتطلب السياج المكون من n قسمًا n + 1 عمودًا.

الإجابة الشائعة التي تقول إن عدد الأعمدة عشرة خاطئة. هذه الإجابة ناتجة عن قسمة طول السياج على المسافة بين كل عمود وآخر، حيث يُصنّف الناتج خطأً على أنه عدد الأعمدة. في الواقع، يتكون السياج من عشرة أقسام وأحد عشر عمودًا.

في هذا السيناريو، سيحتوي السياج المكون من n قسمًا على n + 1 عمودًا. وعلى العكس، إذا كان السياج يحتوي على n عمودًا، فسيحتوي على n - 1 قسمًا. من المهم مراعاة هذه العلاقة عند التعامل مع الخطأ العكسي. يحدث الخطأ العكسي عندما يكون عدد الأعمدة معروفًا ويُفترض أن عدد الأقسام هو نفسه. اعتمادًا على تصميم السياج، قد يكون هذا الافتراض صحيحًا أو خاطئًا.

توضح المشكلة التالية الخطأ العكسي:

إذا كان لديك عدد n من المنشورات، فكم عدد الأقسام الموجودة بينها؟

يؤدي تفسير تصميم السياج إلى تغيير إجابة هذه المسألة. يكون عدد أقسام السياج الصحيح n - 1 إذا كان السياج عبارة عن قطعة مستقيمة قائمة بذاتها ومحاطة بعمود عند كل طرف (مثل سياج بين ممرين)، أو n إذا كان السياج يشكل حلقة كاملة قائمة بذاتها (مثل حظيرة يمكن الوصول إليها بالتسلق، كحلبة ملاكمة)، أو n + 1 إذا لم تكن هناك أعمدة عند نهايات السياج الذي يشبه القطعة المستقيمة (مثل سياج بين مبنيين مثبتين بجدار). يجب دراسة تعريف المسألة بدقة، لأن الإعداد في حالة معينة قد يعطي إجابة خاطئة في حالات أخرى.

قد تحدث أخطاء في حسابات أعمدة السياج في وحدات أخرى غير الطول. على سبيل المثال، من المقرر أن يستغرق بناء هرم الزمن ، المكون من 120 مكعبًا موضوعة على فترات عشر سنوات بين كل مكعب وآخر، 1190 عامًا (وليس 1200 عامًا)، بدءًا من تركيب المكعب الأول وحتى تركيب المكعب الأخير. ومن أوائل أخطاء حسابات أعمدة السياج ما يتعلق بالوقت، حيث احتسب التقويم اليولياني في الأصل السنوات الكبيسة بشكل خاطئ ، نظرًا لحسابها بشكل شامل بدلًا من حسابها بشكل حصري، مما أدى إلى سنة كبيسة كل ثلاث سنوات بدلًا من كل أربع سنوات.

مثال على هذا الخطأ قد يحدث في لغة البرمجة MATLAB مع دالة linspace()الاستيفاء الخطي ، حيث تكون معاملاتها هي و وليس . قد يعتقد المبرمج الذي يسيء فهم المعامل الثالث على أنه عدد الزيادات أن الدالة ستحقق متتالية، لكنه سيحصل بدلاً من ذلك على .(lower value, upper value, number of values)(lower value, upper value, number of increments)linspace(0,10,5)[0, 2, 4, 6, 8, 10][0, 2.5, 5, 7.5, 10]

التكرار على المصفوفات

لنفترض وجود مصفوفة من العناصر، ونريد معالجة العناصر من m إلى n (شاملةً). كم عدد هذه العناصر؟ قد يكون الجواب البديهي nm ، لكنه خاطئ بمقدار عنصر واحد، وهو ما يُعرف بخطأ "الفاصل"؛ والجواب الصحيح هو nm + 1. لهذا السبب، غالبًا ما تُمثَّل النطاقات في الحوسبة بفترات نصف مفتوحة ؛ فالنطاق من m إلى n (شاملةً) يُمثَّل بالنطاق من m (شاملةً) إلى n + 1 (غير شاملةً) لتجنب أخطاء "الفاصل". على سبيل المثال، يمكن كتابة حلقة تكرارية تتكرر خمس مرات (من 0 إلى  4 شاملةً) على شكل فترة نصف مفتوحة من 0 إلى  5.

for ( index = 0 ; index < 5 ; index ++ ) { /* جسم الحلقة */ }

يُنفَّذ جسم الحلقة أولاً عندما تكون قيمة الفهرس تساوي 0؛ ثم تصبح قيمة الفهرس 1، 2، 3، وأخيراً 4 في التكرارات المتتالية. عند هذه النقطة، تصبح قيمة الفهرس 5، لذا فإن الشرط `index < 5` خاطئ، وتنتهي الحلقة. مع ذلك، إذا كانت المقارنة المستخدمة هي `<=` (أصغر من أو يساوي)، فسيتم تنفيذ الحلقة ست مرات: حيث تأخذ قيمة الفهرس القيم 0، 1، 2، 3، 4، و5. وبالمثل، إذا تم تهيئة قيمة الفهرس إلى 1 بدلاً من 0، فسيكون هناك أربع تكرارات فقط: حيث تأخذ قيمة الفهرس القيم 1، 2، 3، و4. كلا البديلين قد يتسببان في أخطاء ناتجة عن اختلاف القيمة بمقدار واحد.

قد يحدث خطأ آخر مماثل إذا استُخدمت حلقة do-while بدلاً من حلقة while (أو العكس). حلقة do-while مضمونة التنفيذ مرة واحدة على الأقل.

قد ينشأ الالتباس المتعلق بالمصفوفات أيضًا من اختلافات لغات البرمجة. يُعد الترقيم من 0 هو الأكثر شيوعًا، لكن بعض اللغات تبدأ ترقيم المصفوفات من 1. تتيح لغة باسكال مصفوفات ذات فهارس يُحددها المستخدم، مما يُتيح نمذجة فهارس المصفوفة وفقًا لمجال المشكلة.

الآثار الأمنية

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

void foo ( char * s ) { char buf [ 15 ]; memset ( buf , 0 , sizeof ( buf )); strncat ( buf , s , sizeof ( buf )); // يجب أن يكون المعامل النهائي: sizeof(buf)-1 }

قد تحدث أخطاء في حساب البايت عند استخدام مكتبة C نظرًا لعدم اتساقها في تحديد ما إذا كان يجب طرح بايت واحد أم لا؛ فبعض الدوال، مثل `and` fgets()و`and`، strncpyلا تكتب أبدًا بعد الطول المحدد لها ( fgets()إذ تطرح `and` بايتًا واحدًا بنفسها، وتسترجع فقط [ n - 1] بايتًا)، بينما دوال أخرى، مثل `and` و`and` strncat، تكتب بعد الطول المحدد لها. في بعض الأنظمة ( خاصةً أنظمة Little Endian )، قد يؤدي هذا السلوك إلى الكتابة فوق البايت الأقل أهمية في مؤشر الإطار . وهذا بدوره قد يُسبب ثغرة أمنية تسمح للمهاجم بالسيطرة على المتغيرات المحلية للدالة المُستدعِية.

إحدى الطرق التي تساعد غالبًا في تجنب هذه المشاكل هي استخدام صيغ مختلفة من هذه الدوال التي تحسب مقدار الكتابة بناءً على الطول الإجمالي للمخزن المؤقت، بدلاً من الحد الأقصى لعدد الأحرف. تشمل هذه الدوال ` strlcatf` و` strlcpyf`، وغالبًا ما تُعتبر "أكثر أمانًا" لأنها تُسهّل تجنب الكتابة عن طريق الخطأ خارج حدود المخزن المؤقت. (في مثال الكود أعلاه، strlcat(buf, s, sizeof(buf))سيؤدي استدعاء `f` بدلاً من ذلك إلى إزالة الخطأ).

انظر أيضاً

مراجع

الاقتباسات

  1. بوليو، ماركوس فيتروفيوس. "الكتاب الثالث، الفصل الرابع، الفقرة الثالثة". دي أركيتكتورا [ في العمارة ] . ترجمة ثاير، بيل.

مصادر

للمزيد من القراءة

  • باركر، مات (2021). باي المتواضع: عندما تخطئ الرياضيات في العالم الحقيقي . دار ريفرهيد للنشر. رقم ISBN 978-0593084694.