Как проверить, близко ли одно число к другому в Python

PythonPythonBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом лабораторном занятии (LabEx) вы научитесь проверять, близко ли одно число к другому на Python, решив проблемы сравнения чисел с плавающей запятой. Сначала вы познакомитесь с концепцией числовой близости и ее важностью, учитывая то, как компьютеры представляют числа с плавающей запятой, что может привести к неожиданным результатам при сравнении их на равенство. Python-скрипт проиллюстрирует эту концепцию, вычислив 0.1 + 0.2 и сравнив результат с 0.3, показывая возможность неравенства из-за представления чисел с плавающей запятой.

Затем в рамках лабораторной работы (LabEx) вы научитесь вычислять абсолютную разность между двумя числами как один из подходов к определению близости. Наконец, вы узнаете, как использовать функцию math.isclose() для более надежного сравнения чисел с плавающей запятой, учитывая как относительную, так и абсолютную погрешность.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python/BasicConceptsGroup -.-> python/numeric_types("Numeric Types") python/ControlFlowGroup -.-> python/conditional_statements("Conditional Statements") python/FunctionsGroup -.-> python/build_in_functions("Build-in Functions") subgraph Lab Skills python/numeric_types -.-> lab-559546{{"Как проверить, близко ли одно число к другому в Python"}} python/conditional_statements -.-> lab-559546{{"Как проверить, близко ли одно число к другому в Python"}} python/build_in_functions -.-> lab-559546{{"Как проверить, близко ли одно число к другому в Python"}} end

Понимание числовой близости

На этом этапе мы рассмотрим концепцию числовой близости и ее важность в программировании, особенно при работе с числами с плавающей запятой. Из-за того, как компьютеры представляют числа с плавающей запятой, они часто являются приближениями действительных чисел. Это может привести к неожиданным результатам при сравнении их на равенство.

Числовая близость помогает нам определить, достаточно ли "близки" два числа, чтобы считать их равными, даже если они не совпадают точно. Это особенно полезно при выполнении вычислений, которые включают арифметические операции с числами с плавающей запятой.

Начнем с создания Python-скрипта для иллюстрации этой концепции.

  1. Откройте редактор VS Code в среде LabEx.

  2. Создайте новый файл с именем proximity.py в директории ~/project.

    ~/project/proximity.py
  3. Добавьте следующий код в файл proximity.py:

    ## proximity.py
    
    num1 = 0.1 + 0.2
    num2 = 0.3
    
    print(f"num1 is: {num1}")
    print(f"num2 is: {num2}")
    
    if num1 == num2:
        print("num1 and num2 are equal")
    else:
        print("num1 and num2 are not equal")

    Этот скрипт вычисляет 0.1 + 0.2 и сравнивает результат с 0.3.

  4. Сохраните файл и запустите его, используя следующую команду в терминале:

    python ~/project/proximity.py

    Вы должны увидеть вывод, похожий на следующий:

    num1 is: 0.30000000000000004
    num2 is: 0.3
    num1 and num2 are not equal

    Как вы можете видеть, num1 и num2 не совпадают точно из-за представления чисел с плавающей запятой, хотя математически они должны быть равны. Именно здесь концепция числовой близости становится важной. В следующих шагах мы рассмотрим способы обработки такой ситуации.

Вычисление абсолютной разности

На этом этапе мы научимся вычислять абсолютную разность между двумя числами. Абсолютная разность представляет собой величину разности между двумя числами, независимо от их порядка. Другими словами, это положительная разность между двумя числами.

В Python мы можем использовать функцию abs() для вычисления абсолютной разности. Функция abs() возвращает абсолютное значение числа.

Давайте модифицируем скрипт proximity.py из предыдущего шага, чтобы вычислить абсолютную разность между num1 и num2.

  1. Откройте файл proximity.py в директории ~/project с помощью редактора VS Code.

  2. Измените код для вычисления абсолютной разности:

    ## proximity.py
    
    num1 = 0.1 + 0.2
    num2 = 0.3
    
    print(f"num1 is: {num1}")
    print(f"num2 is: {num2}")
    
    absolute_difference = abs(num1 - num2)
    print(f"The absolute difference between num1 and num2 is: {absolute_difference}")
    
    if absolute_difference < 0.00001:  ## Using a small tolerance
        print("num1 and num2 are approximately equal")
    else:
        print("num1 and num2 are not approximately equal")

    В этом коде мы вычисляем абсолютную разность между num1 и num2 с помощью функции abs(). Затем мы сравниваем абсолютную разность с небольшим значением допуска (в данном случае 0.00001). Если абсолютная разность меньше допуска, мы считаем числа приблизительно равными.

  3. Сохраните файл и запустите его, используя следующую команду в терминале:

    python ~/project/proximity.py

    Вы должны увидеть вывод, похожий на следующий:

    num1 is: 0.30000000000000004
    num2 is: 0.3
    The absolute difference between num1 and num2 is: 4.440892098500626e-17
    num1 and num2 are approximately equal

    Теперь скрипт правильно определяет, что num1 и num2 приблизительно равны, учитывая абсолютную разность и значение допуска. Этот подход более надежен, чем прямое сравнение чисел с плавающей запятой на равенство.

Использование функции math.isclose() для чисел с плавающей запятой

На этом этапе мы научимся использовать функцию math.isclose() для сравнения чисел с плавающей запятой на приблизительное равенство. Функция math.isclose() является более надежным и рекомендуемым способом сравнения чисел с плавающей запятой, чем использование фиксированного допуска.

Функция math.isclose() принимает два числа в качестве входных параметров и возвращает True, если они близки друг к другу в пределах заданного допуска, и False в противном случае. Она имеет два параметра допуска: rel_tol (относительный допуск) и abs_tol (абсолютный допуск).

Давайте модифицируем скрипт proximity.py из предыдущего шага, чтобы использовать функцию math.isclose().

  1. Откройте файл proximity.py в директории ~/project с помощью редактора VS Code.

  2. Измените код для использования math.isclose():

    ## proximity.py
    
    import math
    
    num1 = 0.1 + 0.2
    num2 = 0.3
    
    print(f"num1 is: {num1}")
    print(f"num2 is: {num2}")
    
    if math.isclose(num1, num2):
        print("num1 and num2 are approximately equal")
    else:
        print("num1 and num2 are not approximately equal")

    В этом коде мы импортируем модуль math и используем функцию math.isclose() для сравнения num1 и num2. Мы используем значения по умолчанию для rel_tol и abs_tol, которые подходят для большинства случаев.

  3. Сохраните файл и запустите его, используя следующую команду в терминале:

    python ~/project/proximity.py

    Вы должны увидеть вывод, похожий на следующий:

    num1 is: 0.30000000000000004
    num2 is: 0.3
    num1 and num2 are approximately equal

    Теперь скрипт правильно определяет, что num1 и num2 приблизительно равны, используя функцию math.isclose(). Это рекомендуемый способ сравнения чисел с плавающей запятой на приблизительное равенство в Python.

Резюме

В этом практическом занятии (лабораторной работе) мы начали с исследования концепции числовой близости и ее важности при сравнении чисел с плавающей запятой в Python. Из-за того, как компьютеры представляют эти числа, прямые сравнения на равенство могут быть ненадежными. Мы создали скрипт proximity.py, чтобы продемонстрировать эту проблему, где сравнивали 0.1 + 0.2 с 0.3 и выяснили, что они не точно равны из-за представления чисел с плавающей запятой.

Затем в рамках практического занятия была показана необходимость альтернативных методов для определения того, являются ли два числа "достаточно близкими", чтобы считать их равными. Это послужило основой для изучения таких методов, как вычисление абсолютной разности на последующих этапах (содержание обрезано).