简介
浮点数在 Python 中广泛用于数值计算,但在比较值时,其表示方式有时会导致意外行为。本教程将引导你了解 Python 中浮点数表示的基础知识,并提供处理精确浮点数比较的实用技术。
Python 中的浮点数表示
在 Python 中,浮点数使用 IEEE 754 标准表示,这是计算机中广泛采用的表示实数的标准。该标准定义了浮点算术的格式和行为,包括正无穷、负无穷和非数字(NaN)等特殊值的表示。
浮点数表示
Python 中的浮点数以 64 位格式存储,也称为“双精度”浮点数。这种格式由三个部分组成:
- 符号位:确定数字是正数还是负数。
- 指数:表示尾数要乘的 2 的幂。
- 尾数:数字的小数部分。
Python 中浮点数的表示可以可视化如下:
graph TD
A[符号位] --> B[指数]
B --> C[尾数]
IEEE 754 标准定义了用于表示特殊值的特定位模式,例如正零、负零、正无穷、负无穷和 NaN。
精度和舍入
由于用于表示数字的位数有限,计算机中的浮点算术并不总是精确的。这可能导致在比较浮点值时出现舍入误差和意外行为。例如,以下代码演示了这个问题:
import sys
x = 0.1
y = 0.2
print(x + y) ## 输出:0.30000000000000004
出现这种行为的原因是,0.1 和 0.2 的二进制表示无法在用于存储浮点数的有限位数中精确表示。
为了解决这个问题,下一节将讨论各种精确浮点比较的技术。
比较浮点数
由于浮点数表示中固有的不精确性,在 Python 中比较浮点数可能具有挑战性。可以使用以下技术来执行精确的浮点数比较:
绝对差比较
最简单的方法是检查两个浮点数之间的绝对差是否小于一个小的阈值。当你知道要比较的值的预期精度时,此方法适用。
import sys
x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon ## 使得 1.0 + x!= 1.0 的最小正浮点数 x
if abs(x + y - 0.3) < epsilon:
print("x + y 等于 0.3")
else:
print("x + y 不等于 0.3")
相对差比较
在被比较的数字大小不同的情况下,相对差比较可能更合适。此方法检查数字之间的绝对差与数字大小相比是否小。
import sys
x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
print("x 等于 y")
else:
print("x 不等于 y")
最后一位单位(ULP)比较
ULP 比较方法检查两个浮点数之间的差是否小于最后一位的某个单位数(ULP)。此方法比绝对或相对差比较方法更精确。
import math
x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
print("x 等于 y")
else:
print("x 不等于 y")
通过使用这些技术,你可以在 Python 中有效地比较浮点数,并处理其表示中固有的不精确性。
精确浮点数比较的技巧
在 Python 中处理浮点数时,使用适当的技巧以确保精确比较非常重要。以下是一些你可以使用的技巧:
绝对差比较
绝对差比较检查两个浮点数之间的绝对差是否小于一个小的阈值。当你知道要比较的值的预期精度时,此方法适用。
import sys
x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon ## 使得 1.0 + x!= 1.0 的最小正浮点数 x
if abs(x + y - 0.3) < epsilon:
print("x + y 等于 0.3")
else:
print("x + y 不等于 0.3")
相对差比较
相对差比较检查两个浮点数之间的绝对差与这些数字的大小相比是否小。当被比较数字的大小不同时,此方法很有用。
import sys
x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
print("x 等于 y")
else:
print("x 不等于 y")
最后一位单位(ULP)比较
ULP 比较方法检查两个浮点数之间的差是否小于最后一位的某个单位数(ULP)。此方法比绝对或相对差比较方法更精确。
import math
x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
print("x 等于 y")
else:
print("x 不等于 y")
通过使用这些技巧,你可以在 Python 中有效地处理浮点数比较,并确保计算中达到所需的精度水平。
总结
在本 Python 教程中,你已经了解了浮点数表示的挑战以及执行精确浮点数比较的有效策略。通过理解基本原理并应用所涵盖的技术,你可以编写更健壮、更可靠的 Python 代码,从而准确地处理浮点运算和比较。



