云计算百科
云计算领域专业知识百科平台

(学习笔记)2.4 浮点运算(2.4.5 浮点运算&2.4.6 C语言中的浮点数)

文章目录

  • 线索栏
  • 笔记栏
    • 1. IEEE浮点运算规则
      • 1)基本定义
      • 2)特殊值规则
    • 2. 浮点运算的代数属性
      • 1)浮点加法 (

        +

        f

        +^f

        +f​)

      • 2)浮点乘法 (

        f

        ∗^f

        f)

    • 3. C语言中的浮点数
      • 1)类型对应
      • 2)访问特殊值
      • 3)练习题2.53(定义无穷和-0)
    • 4. 浮点与整数的类型转换规则
    • 5. 旁注:Ariane 5 事故(1996)
    • 6. 练习题2.54 (假设int为32位)
  • 总结栏

线索栏

  • IEEE浮点运算的基本规则是什么?如何处理特殊值(如无穷、NaN)?
  • 浮点加法具有结合性吗?为什么?请举例说明。
  • 浮点运算满足哪些代数性质(可交换、单调性)?不满足哪些(结合、分配)?
  • C语言中float和double类型与IEEE标准有何关系?如何定义无穷大和NaN?
  • 在不同数值类型(int, float,double)间进行强制类型转换时,遵循什么原则?
  • Ariane 5火箭爆炸事故的技术根源是什么?带来了什么教训?
  • (练习题2.54)哪些类型转换或表达式是绝对安全的?哪些可能出错?

  • 笔记栏

    1. IEEE浮点运算规则

    1)基本定义

    对于实数运算 ⊙,浮点运算定义为 Round(x⊙y),即对精确数学结果进行舍入。

    2)特殊值规则

    标准明确定义了涉及特殊值(

    0

    ,

    ±

    ,

    N

    a

    N

    −0, ±\\infty, NaN

    0,±,NaN)的运算,使其行为合理。例如: (1)

    1

    0

    \\frac1{−0}→−\\infty

    01 (2)

    1

    +

    0

    +

    \\frac1{+0}→+\\infty

    +01+ (3)

    =

    N

    a

    N

    \\infty−\\infty=NaN

    =NaN (4)任何涉及

    N

    a

    N

    NaN

    NaN的运算结果均为

    N

    a

    N

    NaN

    NaN

    2. 浮点运算的代数属性

    1)浮点加法 (

    +

    f

    +^f

    +f​)

    (1)可交换:

    x

    +

    f

    y

    =

    y

    +

    f

    x

    x+^f​y=y+^f​x

    x+fy=y+fx。 (2)不可结合:

    (

    x

    +

    f

    y

    )

    +

    f

    z

    x

    +

    f

    (

    y

    +

    f

    z

    )

    (x+^fy)+^f​z\\neq x+^f​(y+^f​z)

    (x+fy)+fz=x+f(y+fz)。 (3)示例(单精度):(3.14+1e10)−1e10=0.0,而 3.14+(1e10−1e10)=3.14。(几乎)存在逆元:

    x

    +

    f

    (

    x

    )

    =

    0

    x+^f ​(−x)=0

    x+f(x)=0。例外是

    \\infty

    N

    a

    N

    NaN

    NaN。 (4)满足单调性:若

    a

    b

    a≥b

    ab,则对任意非

    N

    a

    N

    NaN

    NaN

    x

    x

    x,有

    x

    +

    f

    a

    x

    +

    f

    b

    x+^f​a≥x+^f​b

    x+fax+fb

    2)浮点乘法 (

    f

    ∗^f

    f)

    (1)可交换:

    x

    f

    y

    =

    y

    f

    x

    x∗^f​y=y∗^f​x

    xfy=yfx。 (2)不可结合:

    (

    x

    f

    y

    )

    f

    z

    x

    f

    (

    y

    f

    z

    )

    (x∗^f​y)∗^f​z\\neq x∗^f​(y∗^f ​z)

    (xfy)fz=xf(yfz)。 示例(单精度):(1e20∗1e20)∗1e−20=+∞,而 1e20∗(1e20∗1e−20)=1e20。 (3)不满足分配律:

    a

    f

    (

    b

    +

    f

    c

    )

    (

    a

    f

    b

    )

    +

    f

    (

    a

    f

    c

    )

    a∗^f​(b+^f​c)\\neq(a∗^f​b)+^f​(a∗^f​c)

    af(b+fc)=(afb)+f(afc)。 示例:1e20∗(1e20−1e20)=0.0,而 (1e20∗1e20)−(1e20∗1e20)=NaN。 (4)满足单调性: 若

    a

    b

    a≥b

    ab

    c

    0

    c≥0

    c0,则

    a

    f

    c

    b

    f

    c

    a∗^f​c≥b∗^f​c

    afcbfc。 若

    a

    b

    a≥b

    ab

    c

    0

    c≤0

    c0,则

    a

    f

    c

    b

    f

    c

    a∗^f​c≤b∗^f​c

    afcbfc。 (5)非负性:只要

    a

    N

    a

    N

    a\\neq NaN

    a=NaN,就有

    a

    f

    a

    0.0

    a∗^f​a≥0.0

    afa0.0

    3. C语言中的浮点数

    1)类型对应

    在支持IEEE的机器上,float↔ 单精度,double↔ 双精度。舍入方式默认为向偶数舍入。

    2)访问特殊值

    C标准不强制要求IEEE,因此访问特殊值(±∞, NaN)是编译器相关的。例如,在GCC中:

    #define _GNU_SOURCE 1
    #include <math.h>
    // 之后可使用 INFINITY 和 NAN

    3)练习题2.53(定义无穷和-0)

    利用溢出到无穷的特性。 在这里插入图片描述

    #define POS_INFINITY (1.0/0.0) // 或 1e400
    #define NEG_INFINITY (POS_INFINITY)
    #define NEG_ZERO (0.0)

    在这里插入图片描述

    4. 浮点与整数的类型转换规则

    (1)int→ float:不会溢出,但可能被舍入(精度损失)。 (2)int/float→ double:double精度更高范围更大,可保留精确值。 (3)double→ float:可能溢出为 ±∞,或因精度降低被舍入。 (4)float/double→ int: 值将向零舍入(截断)。 可能溢出,C标准未定义结果。在x86系统上,会得到“整数不确定值” TMin_w。

    5. 旁注:Ariane 5 事故(1996)

    (1)直接原因:64位浮点数(水平速率)转换为16位整数时发生溢出。这个溢出值被误当作有效数据发送,导致火箭失控爆炸。 (2)根本原因:代码从Ariane 4重用,但未重新验证假设。Ariane 5的速度远超Ariane 4,使原16位整数范围假设失效。 (3)教训: 对浮点到整数的转换必须进行严格的边界检查。 重用代码时,必须重新评估其前置条件和假设。 系统安全不能依赖于“理论上不会发生”的假设。

    6. 练习题2.54 (假设int为32位)

    在这里插入图片描述 在这里插入图片描述


    总结栏

    本节综合探讨了浮点数的运算规则、C语言实现及其实践教训。

  • 运算的本质:IEEE浮点运算是对精确数学结果进行舍入。它保留了可交换性、单调性等良好性质,但牺牲了结合性和分配律。这使得编译器优化和数值程序推理变得复杂。
  • C语言的映射与局限:C的float/double通常对应IEEE格式,但标准未强制,导致访问特殊值等操作依赖编译器扩展。类型转换规则揭示了精度与范围的权衡:大类型转小类型可能舍入或溢出,浮点转整数会截断并可能溢出。
  • 血的教训:Ariane5事故是工程史上的经典失败案例。它警示我们:永远不要忽视浮点运算(特别是向整数转换)的边界条件;代码重用必须重新验证其运行环境的假设。
  • 核心编程意识:程序员必须意识到,浮点运算是近似但确定的。理解其规则(如练习题2.54所示)是预测程序行为、避免微妙错误、编写可靠数值代码的基础。在涉及精度转换和混合类型运算时,必须保持高度警惕。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » (学习笔记)2.4 浮点运算(2.4.5 浮点运算&2.4.6 C语言中的浮点数)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!