数字

计算机被设计用于执行数值计算,但每个处理定量数据的程序员都应该了解一些关于数字处理的重要细节。Python(与大多数其他编程语言一样)区分两种不同类型的数字:

  • 整数在 Python 语言中被称为 int 值。它们只能表示没有小数部分的整数(负数、零或正数)。
  • 实数在 Python 语言中被称为 float 值(或浮点值)。它们可以表示整数或分数,但存在一些限制。

数字的类型从其显示方式可以明显看出:int 值没有小数点,而 float 值总是包含小数点。

[In ]:
# Some int values
2
2
[In ]:
1 + 3
4
[In ]:
-1234567890000000000
-1234567890000000000
[In ]:
# Some float values
1.2
1.2
[In ]:
3.0
3.0

float 值与 int 值通过某种算术运算符进行运算时,结果始终是 float 值。在大多数情况下,两个整数运算得到另一个整数,但任何数字(intfloat)除以另一个数字的结果都是 float 值。非常大或非常小的 float 值会以科学记数法显示。

[In ]:
1.5 + 2
3.5
[In ]:
3 / 1
3.0
[In ]:
-12345678900000000000.0
-1.23456789e+19

type 函数可用于查找任何数字的类型。

[In ]:
type(3)
int
[In ]:
type(3 / 1)
float

表达式的 type 是其最终值的类型。因此,type 函数永远不会指示表达式的类型是一个名称,因为名称总是被求值为其赋值的值。

[In ]:
x = 3
type(x) # The type of x is an int, not a name
int
[In ]:
type(x + 2.5)
float

关于浮点值的更多内容

浮点值非常灵活,但它们确实存在局限性。

  1. float 可以表示极大和极小的数字。虽然存在极限,但你很少会遇到它们。
  2. float 对于任何数字只能表示 15 或 16 位有效数字;其余精度会丢失。这种有限的精度对于绝大多数应用来说已经足够。
  3. 在对 float 值进行算术运算后,最后几位数字可能不准确。初次遇到小的舍入误差时,往往会令人困惑。

第一个限制可以通过两种方式观察到。如果计算结果是一个非常巨大的数字,那么它会被表示为无穷大。如果结果是一个非常小的数字,那么它会被表示为零。

[In ]:
2e306 * 10
2e+307
[In ]:
2e306 * 100
inf
[In ]:
2e-322 / 10
2e-323
[In ]:
2e-322 / 100
0.0

第二个限制可以通过一个涉及超过 15 位有效数字的表达式来观察。这些额外的数字在进行任何算术运算之前会被丢弃。

[In ]:
0.6666666666666666 - 0.6666666666666666123456789
0.0

第三个限制可以在计算两个本应相等的表达式之间的差值时观察到。例如,表达式 2 ** 0.5 计算 2 的平方根,但对该值求平方并不能精确恢复 2。

[In ]:
2 ** 0.5
1.4142135623730951
[In ]:
(2 ** 0.5) * (2 ** 0.5)
2.0000000000000004
[In ]:
(2 ** 0.5) * (2 ** 0.5) - 2
4.440892098500626e-16

上述最终结果是 0.0000000000000004440892098500626,一个非常接近零的数字。该算术表达式的正确答案是 0,但最后一位有效数字上的微小误差在科学记数法中看起来差异很大。这种行为几乎出现在所有编程语言中,因为它是计算机执行算术运算的标准方式所导致的结果。

尽管 float 值并不总是精确的,但它们确实是可靠的,并且在所有不同类型的计算机和编程语言中以相同的方式工作。