CodeGym /课程 /Python SELF ZH /处理浮点数

处理浮点数

Python SELF ZH
第 5 级 , 课程 4
可用

4.1 浮点数的舍入

浮点数在英语里叫做 floating point number — 小数点数:在美国,使用句号来分隔整数部分和小数部分。因此有了float这个名字。

正如我们已经讨论过的那样,当将浮点数(float)转换为整数(int)时,始终会向下舍入为最近的整数——其小数部分直接被舍弃。不过,很容易想象这样的情况:当一个浮点数需要仅舍入到最近的整数时,该怎么办?

对此,Python 中有一个内置函数round()。这个函数是在 math 库创建之前就被发明出来的,所以它不属于 math 库。用于向下舍入和向上舍入的函数在 math 库中。

round() 函数将数字舍入到最近的整数:


round(浮点数)

这个函数将返回最接近传入的浮点数的整数。重要的是要注意,如果数字的小数部分等于 0.5,函数 round() 会使用舍入到最近的偶数整数的方法。这被称为“银行家舍入”,用于减少多次舍入时的系统误差。例如:

示例:

命令 结果
x = round(4.1) 4
x = round(4.5) 4
x = round(4.9) 5
x = round(5.5) 6

math.ceil() 函数将数字向上舍入为整数,示例:

命令 结果
x = math.ceil(4.1) 5
x = math.ceil(4.5) 5
x = math.ceil(4.9) 5

math.floor() 函数将数字向下舍入为整数,示例:

命令 结果
x = math.floor(4.1) 4
x = math.floor(4.5) 4
x = math.floor(4.9) 4

尽管如此,要向下舍入数字,更简单的方法是使用类型转换函数 int()

命令 结果
x = int(4.9) 4

如果你记不住这些命令,一个简单的英文课可以帮助你:

  • math — 数学
  • round — 圆/舍入
  • ceiling — 天花板
  • floor — 地板

4.2 浮点数的结构

在 Python 中,float 类型可以存储从 -1.7*10308 到 +1.7*10308 的值。这样庞大的数值范围是因为 float 类型与整数类型的构造完全不同。每个浮点型变量包含两个数字:第一个称为尾数,第二个是指数。

假设我们有一个数字 123456789,并将其存储在一个 float 类型的变量中。那么这个数字会被转换成 1.23456789*108,在 float 类型内部将存储两个数字——234567898。 红色部分是“数字的有效部分”(尾数),绿色部分是指数。

这种方法允许存储非常大的数字,也能存储非常小的数字。不过由于数字大小受限于 8 字节(64 位),并且部分位用于存储 指数(以及数字的符号和指数的符号),因此尾数的最大长度限制为 15 位数。

这是对浮点数的一个非常简化的描述,更完整的可以在网上搜索。

4.3 使用浮点数时的精度丢失

使用浮点数时,总要记住,浮点数是 不精确的。始终会有舍入误差,转换误差从十进制到二进制,最后,最常见的就是精度丢失在相加/减去大小相差甚远的数字时。

最后一种情况是编程新手最意想不到的。

如果从数字 109 中减去 1/109,我们又会得到 109

减去大小相差甚远的数字 解释

1000000000.000000000
-     0.000000001
1000000000.000000000
                            
第二个数字太小了,其有效部分被忽略(用灰色突出显示)。橙色部分标出的是15个有效数字

这里要说的是,编程不是数学。

4.4 比较浮点数的危险

还有一个危险在于比较浮点数时。由于在处理这些数字时可能会累积舍入误差,因此可能会出现这样的情况:浮点数应该相等但实际上不等,反之亦然:数字应该不等但它们相等。

例子:

命令 解释
a = 1000000000.0 b = 0.000000001 c = a – b

变量 a 中的值为 1000000000.0

变量 c 中的值为 1000000000.0

(变量 b 中的数字太小了)

在上面的例子中,a 和 c 不应该相等,但它们相等。

或者我们来看另一个例子:

命令 解释
a = 1.00000000000000001 b = 1.00000000000000002

变量 a 中的值为 1.0

变量 b 中的值为 1.0

在实际操作中,浮点数是这样比较的:

取一个非常小的数字。如果两个数字之差(绝对值)小于这个小数字,则认为它们是相等的。示例:


a = 0.00000000012
b = 0.000000000011 

if abs(a - b) < 0.00001:
    print("相等")
else:
    print("不相等")
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION