Python 语言提供了类型 float 用于表示浮点数。float 类型的字面值形式与数学中的 写法基本一致,但是允许小数点后面没有任何数字(表示小数部分为 0),例如下列字面值 都是浮点数:

    Python 为浮点数类型提供了通常的加减乘除等运算,运算符与整数类型是一样的(见 表 2.1)。但是,与整数类型不同的是,运算符“/”用于浮点数时,是要保留小数部分的, 例如:

    1. 3.6666666666666665

    没错,最后一位小数是 5 而不是 6!原因见下面关于浮点数内部表示的内容。 将一个浮点数赋值给变量,则该变量就是 float 类型(实际上是指向一个 float 类型的数据)。例如:

    1. >>> f = 3.14
    2. >>> type(f)
    3. <type 'float'>

    浮点数运算同样可以和变量赋值结合起来,形成如表 2.2 所示的简写形式。

    浮点数的能力与限制 浮点数类型能够表示巨大的数值,能够进行高精度的计算。但是,由于浮点数在计算机

    内是用固定长度的二进制表示的,有些数可能无法精确地表示,只能存储带有微小误差的近 似值。例如,

    1. >>> 1.2 1.0
    2. 0.19999999999999996

    结果比 0.2 略小。又如:

    1. >>> 2.2 1.2
    2. 1.0000000000000002

    结果比 1.0 略大。然而,下面这个表达式却计算出了精确结果:

    尽管浮点表示带来的这种微小误差不至于影响数值计算实际应用,但在程序设计中仍然 可能导致错误。例如,万一某个程序中需要比较 2.2 ? 1 是否等于 1.2,那我们就得不到 预期的肯定回答,因为 Python 的计算结果是不相等!请看下面两个比较式:

    1. >>> (1.2 1.0) == 0.2
    2. False
    3. >>> (2.0 1.0) == 1.0
    4. True
    1. True

    另外从运算效率考虑,与整数类型 int 相比,浮点数类型 float 的运算效率较低,由 此我们得出另一条经验:如果不是必须用到小数,那就应当使用整数类型。

    科学记数法

    对于很大或很小的浮点数,Python 会自动以科学记数法来表示。所谓科学记数法就是

    以“a×10 的整数次幂”的形式来表示数值,其中 1 <= abs(a) < 10。例如,12345 可 以表示成 1.2345e+4,0.00123 可以表示为 1.2345e-3。下面是 Python 的计算例子:

    1. >>> 1234.5678 ** 9
    2. 6.662458388479362e+27
    3. >>> 1234.5678 ** -9
    4. 1.5009474606688535e-28

    正如 int 不同于整数集 I 一样,Python 的 float 也不同于实数集 R,因为 float 仍 然只能表示有限的浮点数。当一个表达式的结果超出了浮点数表示范围的时候,Python 会 显示结果为 inf(无穷大)或-inf(负无穷)。读者可以做一个有趣但略显麻烦的实验,试 一试 Python 最大能表示多大的浮点数。下面是本书著者所做的实验结果,可以看到,最大 浮点数的数量级是 10308,有效数字部分已经精确到小数点后面第 53 位(Python 在显示结果 时只保留小数点后 16 位),当该位为 6 时是合法的浮点数,当该位为 7 时则超出范围。

    1. >>> 1.79769313486231580793728971405303415079934132710037826e+308
    2. 1.7976931348623157e+308
    3. >>> 1.79769313486231580793728971405303415079934132710037827e+308
    4. inf

    顺便说一下,如果读者做这个实验,相信你一定会采用一种快速有效的策略来确定每一 位有效数字,而不会对每一位都从 0 试到 9。例如,当发现 1.7…1e+308 是合法的浮点数, 而 1.7…9e+308 超出了范围,接下去应当检查 1.7…5e+308 的合法性。这种方法就是本 书后面算法设计一章中介绍的二分查找策略。我们在第 1 章说过,计算思维人人皆有、处处 可见,不是吗?

    自动类型转换

    float 类型与 float 类型的数据相互运算,结果当然是 float 类型。问题是 float 类型能与 int 或 long 类型进行运算吗?

    由于整数、长整数和浮点数都是数值(在数学上都属于实数集合 R),因此 Python 允许

    手动类型转换

    除了在计算混合类型的表达式时 Python 自动进行类型转换之外,有时我们还需要自己 手动转换类型。这是通过几个类型函数 int()、long()和 float()实现的。例如,当我 们要计算一批整型数据的平均值,程序中一般会先求出这批数据的总和 sum,然后再除以数 据的个数 n,即:

    1. average = sum / n

    但这个结果未必如我们所愿,因为 sum 和 n 都是整数,Python 执行的是整数除法,小数部 分被舍弃了,导致结果误差太大。为解决此问题,我们需要手动转换数据类型:

    1. average = float(sum) / n

    其中 float()函数将 int 类型的 sum 转换成了 float 类型,而 n 无需转换,因为 Python 在计算 float 与 int 混合的表达式时,会自动将 n 转换成 float 类型。

    要注意的是,下面这种转换方式是错误的:

    1. average = float(sum/n)

    因为括号里的算式先计算,得到的就是整除结果,然后再试图转换成 float 类型时,已经 为时已晚,小数部分已经丢失了。

    其实,调用类型函数来手动转换类型并不是好方法,我们有更简单、更高效的做法。如 果已知的数据都是整数类型的,而我们又希望得到浮点类型的结果,那么我们可以将表达式 涉及的某个整数或某一些整数加上小数点,小数点后面再加个 0,这样整数运算就会变成浮 点运算。例如求两个整数的平均值:

    1. >>> z = (x + y) / 2.0
    2. >>> z
    3. 3.5

    例中我们人为地将数据个数 2 写成了 2.0,这样就使计算结果变成了 float 类型。 当然,在将浮点数转换成整数类型时,就没有这种简便方法了,只能通过类型函数来转换。例如:

    可见,float 类型转换成 int 或 long 时,只是简单地舍去小数部分,并没有做四舍五入。 如果希望得到四舍五入的结果,一个小技巧是先为该值(正数)加上 0.5 再转换。更一般 的方法是调用内建函数 round(),它专门用于将浮点数转换成最接近的整数部分。不过舍 入后的结果仍然是 float,为了得到 int 类型的数据还需要再用 int()转换。例如:

    1. >>> round(3.14)
    2. 3.0
    3. >>> round(-3.14)
    4. -3.0
    5. >>> round(3.5)
    6. 4.0
    7. >>> round(-3.5)
    8. -4.0
    9. >>> int(round(-3.14))