سؤال

إذن لدى بايثون لانهاية موجبة وسالبة:

float("inf"), float("-inf")

يبدو أن هذا هو نوع الميزة التي يجب أن تحتوي على بعض التحذيرات.هل هناك أي شيء يجب أن أكون على علم به؟

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

المحلول

ويمكنك الحصول على ما زالت لا واحد في عدد (نان) القيم من حسابية بسيطة تنطوي inf:

>>> 0 * float("inf")
nan

وتجدر الإشارة إلى أنك سوف عادة <م> لا الحصول على قيمة inf من خلال العمليات الحسابية المعتادة:

>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')

وتعتبر قيمة inf قيمة خاصة جدا مع دلالات غير عادية، لذلك فمن الأفضل أن تعرف حول OverflowError على الفور من خلال استثناء، بدلا من وجود قيمة inf حقن بصمت في الحسابات الخاصة بك.

نصائح أخرى

تنفيذ بايثون يتبع معيار IEEE-754 جيد جدًا، والذي يمكنك استخدامه كدليل، ولكنه يعتمد على النظام الأساسي الذي تم تجميعه عليه، لذا اختلافات المنصة قد يحدث.مؤخرًا¹، تم تطبيق إصلاح يسمح بذلك "اللانهاية" وكذلك "inf", ، ولكن هذا له أهمية ثانوية هنا.

تنطبق الأقسام التالية بشكل متساوٍ على أي لغة تنفذ حساب النقطة العائمة لـ IEEE بشكل صحيح، وهي لا تقتصر على لغة Python فقط.

مقارنة لعدم المساواة

عند التعامل مع اللانهاية وأكبر من > أو أقل من < المشغلين، التهم التالية:

  • أي رقم بما في ذلك +inf أعلى من -inf
  • أي رقم بما في ذلك -inf أقل من +inf
  • +inf يكون لا أعلى ولا أقل من +inf
  • -inf ليس أعلى ولا أقل من -inf
  • أي مقارنة تنطوي على NaN هو زائف (inf ليس أعلى ولا أقل من NaN)

المقارنة من أجل المساواة

عند المقارنة من أجل المساواة، +inf و +inf متساوون، كما هي -inf و -inf.هذه قضية محل جدل كبير وقد تبدو مثيرة للجدل بالنسبة لك، لكنها تتوافق مع معيار IEEE وتتصرف بايثون بهذه الطريقة.

بالطبع، +inf غير متكافئ ل -inf وكل شيء، بما في ذلك NaN في حد ذاته، لا يساوي NaN.

الحسابات مع اللانهاية

معظم العمليات الحسابية مع اللانهاية سوف تسفر عن ما لا نهاية، ما لم يكن كلا المعاملين لا نهاية، عند قسمة العملية أو المعامل، أو مع الضرب بصفر، هناك بعض القواعد الخاصة التي يجب وضعها في الاعتبار:

  • عند ضربه بصفر، والنتيجة غير محددة، فإنه ينتج NaN
  • عند قسمة أي رقم (ما عدا اللانهاية نفسها) على اللانهاية، الذي ينتج 0.0 أو -0.0².
  • عند قسمة (بما في ذلك المعامل) اللانهاية الإيجابية أو السلبية على اللانهاية الإيجابية أو السلبية، تكون النتيجة غير محددة، لذلك NaN.
  • عند الطرح قد تكون النتائج مفاجئة، لكن تابع الحس الرياضي المشترك:
    • عند القيام inf - inf, ، النتيجة غير محددة: NaN;
    • عند القيام inf - -inf, ، النتيجه هي inf;
    • عند القيام -inf - inf, ، النتيجه هي -inf;
    • عند القيام -inf - -inf, ، النتيجة غير محددة: NaN.
  • عند الإضافة، قد يكون الأمر مفاجئًا أيضًا:
    • عند القيام inf + inf, ، النتيجه هي inf;
    • عند القيام inf + -inf, ، النتيجة غير محددة: NaN;
    • عند القيام -inf + inf, ، النتيجة غير محددة: NaN;
    • عند القيام -inf + -inf, ، النتيجه هي -inf.
  • استخدام math.pow, pow أو ** أمر صعب، لأنه لا يتصرف كما ينبغي.فإنه يطرح استثناء تجاوز السعة عندما تكون النتيجة ذات رقمين حقيقيين عالية جدًا بحيث لا تتناسب مع تعويم مزدوج الدقة (يجب أن ترجع اللانهاية)، ولكن عندما يكون الإدخال inf أو -inf, فإنه يتصرف بشكل صحيح ويعود أيضًا inf أو 0.0.عندما تكون الحجة الثانية NaN, ، يعود NaN, ، ما لم تكن الوسيطة الأولى كذلك 1.0.هناك المزيد من القضايا، وليس كلها مغطاة في المستندات.
  • math.exp يعاني من نفس المشاكل math.pow.الحل لإصلاح هذا التجاوز هو استخدام تعليمات برمجية مشابهة لما يلي:

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')
    

ملحوظات

ملاحظة 1: كتحذير إضافي، كما هو محدد في معيار IEEE، إذا كانت النتيجة الحسابية الخاصة بك أقل من أو تجاوزت السعة، فلن تكون النتيجة خطأ أقل من أو تجاوز السعة، ولكن لا نهاية إيجابية أو سلبية: 1e308 * 10.0 عائدات inf.

ملاحظة 2: لأن أي حساب مع NaN عائدات NaN وأي مقارنة ل NaN, ، مشتمل NaN في حد ذاته false, ، يجب عليك استخدام math.isnan وظيفة لتحديد ما إذا كان الرقم هو في الواقع NaN.

ملاحظة 3: على الرغم من أن بايثون تدعم الكتابة float('-NaN'), ، تم تجاهل العلامة، لأنه لا يوجد أي تسجيل دخول NaN داخليا.إذا قسمت -inf / +inf, ، النتيجه هي NaN, ، لا -NaN (لا يوجد شيء من هذا القبيل).

ملاحظة 4: كن حذرًا في الاعتماد على أي مما سبق، حيث تعتمد بايثون على مكتبة C أو Java التي تم تجميعها لها ولا تنفذ جميع الأنظمة الأساسية كل هذا السلوك بشكل صحيح.إذا كنت تريد التأكد، فاختبر اللانهاية قبل إجراء حساباتك.

¹) مؤخرا يعني منذ ذلك الحين الإصدار 3.2.
²) تدعم النقاط العائمة الصفر الموجب والسالب، لذا: x / float('inf') يحتفظ بعلامته و -1 / float('inf') عائدات -0.0, 1 / float(-inf) عائدات -0.0, 1 / float('inf') عائدات 0.0 و -1/ float(-inf) عائدات 0.0.فضلاً عن ذلك، 0.0 == -0.0 يكون true, ، يجب عليك التحقق يدويًا من الإشارة إذا كنت لا تريد أن تكون صحيحة.

C99 .

وتمثيل نقطة IEEE 754 عائمة تستخدم من قبل جميع المعالجات الحديثة لديها العديد من أنماط قليلا خاص محفوظة لاللانهاية الإيجابية (علامة = 0، إكسب = ~ 0 فارك = 0)، سلبي لا نهاية (علامة = 1، إكسب = ~ 0، فارك = 0)، والعديد من نان (ليس رقم: إكسب = ~ 0 فارك ≠ 0)

.

وكل ما عليك ما يدعو للقلق: قد يسبب بعض العمليات الحسابية العائمة الاستثناءات نقطة / الفخاخ، ولكن تلك ليست تقتصر على هذه الثوابت "مثيرة للاهتمام"

ولقد وجدت التحذير من أن أحدا لم يذكر حتى الآن. أنا لا أعرف ما إذا كان سوف يأتي في كثير من الأحيان في حالات عملية، ولكن هنا هو من أجل اكتمالها.

وعادة، وحساب اللانهاية عدد مودولو يعود نفسه على تعويم، ولكن جزء مودولو عوائد اللانهاية nan (وليس رقم). هنا مثال:

>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan

وأنا رفعت قضية على بيثون تعقب علة. يمكن أن ينظر إليه على https://bugs.python.org/issue32968 .

تحديث: سيكون هذا الثابتة في بيثون 3.8

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