Engee 文档
Notebook

在Julia中使用近似数比较的一个例子

近似相等的算法被考虑()在Julia编程语言中,它允许您正确比较浮点数。

导言

在编程中使用浮点数时,由于这些数字在计算机内存中的表示精度有限,因此通常难以比较值。

例如,计算的结果 0.1 + 0.2 也许不完全相等 0.3. 为了正确检查两个这样的数字是否彼此接近,使用特殊近似相等方法。

在Julia语言中,函数负责这一点。 (或 isapprox()),它允许您在考虑可能的舍入误差的情况下比较值。 该机制广泛应用于科学计算、测试、数据处理等需要高精度比较的领域。

此示例演示运算符的工作方式。 在不同的数字对集合上。

应用近似相等

让我们创建一个我们将比较的值对列表。

In [ ]:
testvalues = [
    # Примеры с очень большими числами:
    [100000000000000.01,        100000000000000.011], # различаются последним десятичным знаком
    
    # Числа среднего порядка:
    [100.01,                    100.011],             # отличаются больше, чем допустимая погрешность
    
    # Операции деления, где результат может быть неточным из-за представления float:
    [10000000000000.001 / 10000.0, 
     1000000000.0000001000],                          # должно быть равно 1000000000000.001 / 10000 = 100000000.0000001
    
    # Очень маленькие положительные числа:
    [0.001,                     0.0010000001],        # разница в миллионных долях
    
    # Очень маленькое число и ноль:
    [0.000000000000000000000101, 0.0],                # почти равно нулю?

    # Математически равные выражения:
    [sqrt(2) * sqrt(2),         2.0],                 # sqrt(2)^2 = 2, но что получится в результате округлений?
    
    # С отрицательными числами:
    [-sqrt(2) * sqrt(2),       -2.0],                 # аналогично для отрицательного случая

    # Число π записанное разным количеством знаков:
    [3.14159265358979323846,    3.14159265358979324] # различаются на один знак после запятой
]
Out[0]:
8-element Vector{Vector{Float64}}:
 [1.0000000000000002e14, 1.0000000000000002e14]
 [100.01, 100.011]
 [1.0000000000000002e9, 1.0000000000000001e9]
 [0.001, 0.0010000001]
 [1.01e-22, 0.0]
 [2.0000000000000004, 2.0]
 [-2.0000000000000004, -2.0]
 [3.141592653589793, 3.141592653589793]

比较数字

列表中的每对 testvalues 它被顺序取入并存储在变量中 (x, y).

接下来,将信息输出:

-值显示 x,右边补充了长度为21的空格;
-然后显示"≈"符号;
-价值 y,左边补充了长达22的空格;
-冒号后,显示应用运算符的结果。 :真或假。
-这样我们可以立即看到哪些对被认为是近似相等的。

In [ ]:
# Проходимся циклом по всем парам (x, y) из массива
for (x, y) in testvalues
    # Выводим результат сравнения x ≈ y вместе со значениями
    println(
        rpad(x, 21),                      # дополняем x пробелами справа до ширины 21
        " ≈ ",                            # операция приближенного равенства
        lpad(y, 22),                      # дополняем y пробелами слева до ширины 22
        ": ",                             # разделитель перед логическим результатом
        x  y                             # вызываем функцию ≈(x, y) -> Bool
    )
end
1.0000000000000002e14 ≈  1.0000000000000002e14: true
100.01                ≈                100.011: false
1.0000000000000002e9  ≈   1.0000000000000001e9: true
0.001                 ≈           0.0010000001: false
1.01e-22              ≈                    0.0: false
2.0000000000000004    ≈                    2.0: true
-2.0000000000000004   ≈                   -2.0: true
3.141592653589793     ≈      3.141592653589793: true

操作员 . 它是如何工作的?

操作员 在Julia中,它相当于默认调用一个函数。 isapprox(x, y) 使用以下公式:

哪里:

  • (绝对公差):最小绝对误差;
  • (relative tolerance):相对误差。

默认情况下,参数的定义如下:

  • atol = 0
  • rtol = sqrt(eps()) ≈ 1.49e−8

有关该功能的详细资料,亦可在文件

结论

在这个例子中,我们研究了Julia编程语言中近似相等机制的使用。

我们用了操作员 来分析在机器算术不准确的背景下实数之间的差异。

借助此功能,您可以测试计算,对浮点数进行安全比较,以及处理需要容忍小错误的数据。

操作员工作的知识 它对于在数学,物理建模和数据分析领域工作的程序员非常有用。

该示例是使用[Rosetta代码]的材料开发的(https://rosettacode.org/wiki/Approximate_equality