获取Pyhon及副业知识,关注公众号【软件测试圈】
在Python编程中,初学者常会遇到一个令人困惑的问题:为什么 0.1 + 0.2 != 0.3
?这是一个经典的问题,涉及计算机如何表示和处理浮点数。本文将带你一探究竟,揭开浮点数的神秘面纱。
问题描述
首先,让我们看看这个问题:
print(0.1 + 0.2 == 0.3)
print(0.1 + 0.2)
为什么会是 False
呢?让我们分步解析。
浮点数表示的本质
1. 计算机如何表示浮点数
在计算机中,浮点数是以二进制形式存储的,通常采用IEEE 754标准。这个标准定义了浮点数的存储方式,包括符号位、指数位和尾数位。
一个简单的示例可以帮助理解:
0.1 # 用二进制表示是个无穷小数:0.000110011001100110011001100110011...
0.2 # 用二进制表示也是个无穷小数:0.001100110011001100110011001100110...
2. 二进制浮点数的误差
由于浮点数表示的精度有限,计算机无法精确存储这些无穷小数,因此会出现舍入误差。例如:
0.1 # 实际存储的值接近于 0.10000000000000000555...
0.2 # 实际存储的值接近于 0.2000000000000000111...
3. 浮点数运算的误差累积
当你进行 0.1 + 0.2
运算时,实际上是把两个近似值相加:
0.1 + 0.2 # 实际上是 0.10000000000000000555... + 0.2000000000000000111...
结果是:
0.3000000000000000444...
这与 0.3
不完全相同,因为:
0.3 # 实际存储的值接近于 0.2999999999999999889...
因此:
0.1 + 0.2 == 0.3 # 实际比较的是 0.3000000000000000444... == 0.2999999999999999889...
显然,这两个值不相等,结果为 False
。
如何处理浮点数问题
1. 使用math.isclose
函数
Python 提供了 math.isclose
函数,可以方便地比较两个浮点数是否接近。它允许你指定一个相对或绝对误差范围。
import math
print(math.isclose(0.1 + 0.2, 0.3)) # 输出:True
2. 自定义比较函数
你也可以编写自己的函数来比较浮点数:
def is_close(a, b, rel_tol=1e-9, abs_tol=0.0):
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
print(is_close(0.1 + 0.2, 0.3)) # 输出:True
3. 使用Decimal模块
如果需要高精度的计算,可以使用 decimal
模块。它允许你指定精度,并避免浮点数的舍入误差。
from decimal import Decimal
a = Decimal('0.1')
b = Decimal('0.2')
c = Decimal('0.3')
print(a + b == c) # 输出:True
0.1 + 0.2不等于0.3的现象,揭示了计算机在处理浮点数时的精度限制。了解这一点,可以帮助我们更好地编写代码,避免在数值计算中出现意外的错误。