سؤال

هل يمكن أن تخبرني كم هو؟ (-2) % 5؟وفقًا لمترجم Python الخاص بي، فإن الرقم 3، لكن هل لديك تفسير حكيم لذلك؟

لقد قرأت أنه في بعض اللغات يمكن أن تعتمد النتيجة على الآلة، لكنني لست متأكدًا من ذلك.

هل كانت مفيدة؟

المحلول

بالمناسبة:معظم لغات البرمجة ستختلف مع بايثون وتعطي النتيجة -2.اعتمادا على تفسير المعامل هذا صحيح.ومع ذلك، فإن التعريف الرياضي الأكثر اتفاقًا ينص على أن معامل أ و ب هي الراحة (الإيجابية تمامًا). ص من تقسيم أ / ب.بتعبير أدق، 0 <= ص < ب حسب التعريف.

نصائح أخرى

يبدو أن نتيجة عملية المعامل على السلبيات تعتمد على لغة البرمجة وهنا قائمة http://en.wikipedia.org/wiki/Modulo_operation

مترجم بايثون الخاص بك صحيح.إحدى الطرق (الغبية) لحساب المعامل هي طرح المعامل أو إضافته حتى تكون القيمة الناتجة بين 0 و (المعامل - 1).

على سبيل المثال:13 نمط 5 = (13 - 5) نمط 5 = (13 - 10) نمط 5 = 3

أو في حالتك:−2 نمط 5 = (−2 + 5) نمط 5 = 3

كما تقول الوثائق في العمليات الحسابية الثنائية, تؤكد بايثون أن:

يرتبط قسم الأعداد الصحيحة ومشغلي modulo بالهوية التالية: x == (x/y)*y + (x%y).يرتبط قسم الأعداد الصحيحة وmodulo أيضًا بالوظيفة المضمنة divmod(): divmod(x, y) == (x/y, x%y).

وحقاً،

>>> divmod(-2, 5)
(-1, 3).

هناك طريقة أخرى لتصور توحيد هذه الطريقة وهي الحساب divmod لتسلسل صغير من الأرقام:

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

حسنًا، 0% 5 يجب أن يكون 0، أليس كذلك؟

-1% 5 يجب أن يكون 4 لأن هذا هو الرقم المسموح به التالي الذي يسير في الاتجاه المعاكس (أي لا يمكن أن يكون 5، لأنه خارج النطاق).

وباتباع هذا المنطق، يجب أن يكون -2 هو 3.

أسهل طريقة للتفكير في كيفية عمل ذلك هي أن تستمر في إضافة أو طرح 5 حتى يقع الرقم بين 0 (شاملاً) و5 (حصريًا).

لست متأكدًا من الاعتماد على الآلة - لم أر مطلقًا تطبيقًا تم تنفيذه، لكن لا يمكنني القول إنه لم يتم تنفيذه أبدًا.

كما هو موضح في الإجابات الأخرى، هناك العديد من الخيارات لعملية modulo ذات القيم السلبية.بشكل عام، ستعطي اللغات المختلفة (وبنيات الآلات المختلفة) نتائج مختلفة.

بحسب ال دليل بايثون المرجعي,

يُنتج عامل modulo دائمًا نتيجة بنفس إشارة المعامل الثاني (أو الصفر)؛القيمة المطلقة للنتيجة أصغر تمامًا من القيمة المطلقة للمعامل الثاني.

هو الاختيار الذي اتخذته بايثون.يتم تعريف modulo بشكل أساسي بحيث يحمل هذا دائمًا:

x == (x/y)*y + (x%y)

لذلك فمن المنطقي أن (-2)%5 = -2 - (-2/5)*5 = 3

حسنًا، -2 مقسومًا على 5 سيكون 0 والباقي 3.لا أعتقد أن هذا يجب أن يعتمد بشكل كبير على النظام الأساسي، لكنني رأيت أشياء غريبة.

إنه بالفعل 3.في الحساب وحدات, ، المعامل هو ببساطة باقي القسمة، والباقي من -2 مقسومًا على 5 يساوي 3.

النتيجة تعتمد على اللغة.تقوم بايثون بإرجاع علامة المقسوم عليه، حيث تقوم c# على سبيل المثال بإرجاع علامة المقسوم (أي.-2% 5 عوائد -2 في C#).

قد يكون أحد التفسيرات هو أنه يتم تخزين الأرقام السالبة باستخدام تكملة 2.عندما يحاول مترجم بايثون القيام بعملية modulo فإنه يتحول إلى قيمة غير موقعة.على هذا النحو بدلاً من القيام بـ (-2) % 5، فإنه يحسب فعليًا 0xFFFF_FFFF_FFFF_FFFD % 5 وهو 3.

احرص على عدم الاعتماد على سلوك التعديل هذا في C/C++ في جميع أنظمة التشغيل والبنيات.إذا كنت أتذكر بشكل صحيح، فقد حاولت الاعتماد على كود C/C++ مثل

float x2 = x % n;

للاحتفاظ بـ x2 في النطاق من 0 إلى n-1 لكن الأرقام السالبة تسللت عندما كنت أقوم بالتجميع على أحد أنظمة التشغيل، لكن الأمور ستعمل بشكل جيد على نظام تشغيل آخر.أدى هذا إلى تصحيح الأخطاء في وقت شرير لأنه حدث نصف الوقت فقط!

يبدو أن هناك خلطًا شائعًا بين مصطلحي "modulo" و"الباقي".

في الرياضيات، ينبغي أن يكون الباقي دائماً يتم تعريفها بما يتفق مع الحاصل، بحيث إذا a / b == c rem d ثم (c * b) + d == a.اعتمادًا على كيفية تقريب حاصل القسمة الخاص بك، تحصل على بواقي مختلفة.

ومع ذلك، يجب أن يعطي modulo دائمًا نتيجة 0 <= r < divisor, ، وهو ما يتوافق فقط مع التقسيم من التقريب إلى ناقص اللانهاية إذا سمحت بالأعداد الصحيحة السالبة.إذا كانت عملية القسمة تتجه نحو الصفر (وهو أمر شائع)، فإن المعامل والباقي يكونان متكافئين فقط للقيم غير السالبة.

لا تحدد بعض اللغات (خاصة C وC++) سلوكيات التقريب/الباقي المطلوبة و % غامض.يعرف الكثيرون التقريب على أنه نحو الصفر، ومع ذلك يستخدمون المصطلح modulo حيث يكون الباقي أكثر صحة.بايثون غير عادية نسبيًا من حيث أنها تقرب إلى اللانهاية السالبة، لذا فإن المعامل والباقي متساويان.

تتجه Ada نحو الصفر IIRC، لكنها تمتلك كليهما mod و rem العاملين.

تهدف سياسة C إلى السماح للمترجمين باختيار التنفيذ الأكثر كفاءة للجهاز، ولكن IMO يعد تحسينًا خاطئًا، على الأقل هذه الأيام.من المحتمل أن يكون المترجم الجيد قادرًا على استخدام التكافؤ للتحسين حيثما لا يمكن ظهور رقم سالب (وبالتأكيد تقريبًا إذا كنت تستخدم أنواعًا غير موقعة).من ناحية أخرى، عندما يمكن أن تحدث أرقام سالبة، فمن المؤكد تقريبًا أنك تهتم بالتفاصيل - لأسباب تتعلق بقابلية النقل، يتعين عليك استخدام خوارزميات و/أو عمليات فحص معقدة للغاية ومصممة بعناية شديدة لضمان حصولك على النتائج التي تريدها بغض النظر عن التقريب والباقي سلوك.

وبعبارة أخرى، فإن المكسب من هذا "التحسين" هو في الغالب (إن لم يكن دائما) وهم، في حين أن هناك تكاليف حقيقية للغاية في بعض الحالات - لذلك فهو تحسين زائف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top