وحدة في Rust: لا تخلط بينها وبين باقي القسمة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا السؤال عن الوحدة شائع جدًا؟

\n\n

إذا كنت قد كتبت كودًا بلغة Rust وتعاملت مع الأعداد السالبة، فمن المحتمل أنك تساءلت: "أين دالة الوحدة؟". على Stack Overflow، حصد هذا السؤال آلاف المشاهدات، وليس بدون سبب. الحقيقة أن العامل % في Rust ليس وحدة (modulus)، بل هو باقي القسمة (remainder). الفرق دقيق ولكنه حاسم، خاصة في الخوارزميات والتشفير والعمل مع الهياكل الدورية.

\n\n

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

\n\n

ملخص المحتوى

\n
    \n
  • ما هي الوحدة والباقي: الفرق الرياضي
  • \n
  • لماذا % في Rust ليس وحدة
  • \n
  • كيفية كتابة دالة وحدة في Rust
  • \n
  • أمثلة من الحياة الواقعية: المؤشرات الدورية والتجزئة
  • \n
  • الاستنتاجات والنصائح العملية
  • \n
\n\n

الرياضيات: الوحدة مقابل الباقي

\n\n

لنبدأ بالأساسيات. في الرياضيات، الوحدة (modulus) هي عملية تُرجع عددًا غير سالب أصغر من المقسوم عليه. على سبيل المثال:

\n
    \n
  • 7 mod 3 = 1 (7 مقسومة على 3 مع باقي 1)
  • \n
  • -7 mod 3 = 2 (لأن -7 = 3 * (-3) + 2)
  • \n
\n\n

باقي القسمة (remainder) هو ما يتبقى بعد القسمة الصحيحة. في معظم لغات البرمجة (C, C++, Java, Rust)، يُرجع العامل % الباقي، والذي قد يكون سالبًا إذا كان المقسوم سالبًا. مثال:

\n
    \n
  • 7 % 3 = 1 (متطابق)
  • \n
  • -7 % 3 = -1 (في Rust، لأن -7 / 3 = -2، الباقي -1)
  • \n
\n\n

لماذا هذا مهم؟ تخيل أنك تكتب برنامجًا للساعة: الوقت من 0 إلى 23. إذا كانت الساعة الآن 22، وأضفت 5 ساعات، ستحصل على 3 صباحًا. هذا يعمل مع الوحدة: (22 + 5) mod 24 = 3. لكن إذا استخدمت الباقي، فسيفشل الأمر مع القيم السالبة. على سبيل المثال، (-3) % 24 في Rust سيعطي -3، وليس 21.

\n\n

لماذا العامل % في Rust هو remainder

\n\n

في Rust، يُعرّف العامل % على أنه باقي القسمة. هذا مثبت في التوثيق وسلوك المكتبة القياسية. السبب تاريخي: هكذا تم في C والعديد من اللغات الأخرى. تتبع Rust مبدأ "الصريح أفضل من الضمني"، لكن المبتدئين غالبًا ما يقعون في الفخ هنا.

\n\n
fn main() {\n    println!("7 % 3 = {}", 7 % 3);   // 1\n    println!("-7 % 3 = {}", -7 % 3); // -1\n    println!("7 % -3 = {}", 7 % -3); // 1 (نعم، إشارة المقسوم عليه لا تؤثر)\n    println!("-7 % -3 = {}", -7 % -3); // -1\n}
\n\n

لاحظ: إشارة النتيجة تتطابق دائمًا مع إشارة المقسوم. هذا ليس وحدة. للوحدة الحقيقية، يجب أن تكون النتيجة دائمًا غير سالبة.

\n\n

كيفية كتابة دالة الوحدة الحقيقية في Rust؟

\n\n

المكتبة القياسية في Rust لا توفر دالة مدمجة للوحدة (على عكس Python، حيث يعمل % كوحدة). لكن كتابتها بسيطة جدًا. إليك الطريقة الأكثر شيوعًا - من خلال الباقي مع التصحيح.

\n\n

دالة modulus للأعداد الصحيحة

\n\n
fn modulus(a: i32, b: i32) -> i32 {\n    let r = a % b;\n    if r < 0 { r + b.abs() } else { r }\n}\n\nfn main() {\n    println!("modulus(7, 3) = {}", modulus(7, 3));   // 1\n    println!("modulus(-7, 3) = {}", modulus(-7, 3)); // 2\n    println!("modulus(7, -3) = {}", modulus(7, -3)); // 1 (الوحدة دائمًا غير سالبة)\n    println!("modulus(-7, -3) = {}", modulus(-7, -3)); // 2\n}
\n\n

كيف يعمل هذا: نأخذ الباقي a % b. إذا كان سالبًا، نضيف القيمة المطلقة

المدونات

توصيات الكتب