• 浮点数的上溢下溢


    ---------------------------------------------

    原引C Primer Plus (sixth edition)对浮点值上溢下溢的解释:

    假设系统最大的float类型值是3.4E38,编写如下代码:

    float toobig = 3.4E38 * 100.0f;
    printf("%e\n",toobig);

    会发生什么呢?这是一个上溢(overflow)的示例。当计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢。这种行为在过去是未定义的,不过现在C语言规定,在这种情况下会给toobig赋一个表示无穷大的特定值,而且printf()显示该值为inf或infinity(或者具有无穷含义的其他内容)①。

    当初以一个很小的数时,情况更为复杂。回忆一下,float类型的数以指数和尾数部分来储存②。存在这样一个数,它的指数部分是最小值,即由全部可用位表示的最小尾数值。该数字是float类型能用全部精度表示的最小数字。现在把它除以2。通常,这个操作会减小指数部分,但是假设的情况中,指数是最小值了,所以计算机只好把尾数部分的位向右移,空出1个二进制位,并丢弃最后一个二进制数。以十进制为例,把一个4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.123E-10.虽然得到了结果,但是在计算过程中却损失了原本尾有效位上的数字。这种情况叫做下溢(underflow)。C语言把损失了类型全精度的浮点值称为低于正常的(subnormal)浮点值。因此,把最小的正浮点数除以2将得到一个低于正常的值。如果除以一个非常大的值,会导致所有位都为0。现在,C库已提供了用于检查计算是否会产生低于正常值的函数。

    还有另一个特殊的浮点值NaN(not a number的缩写)。例如,给asin()函数传递一个值,该函数将返回一个角度,该角度的正弦就是传入函数的值。但是正弦值不能大于1,因此,如果传入参数大于1,该函数的行为是未定义的。在这种情况下,该函数将返回NaN值,printf()函数可将其显示为nan,Nan或其他类似的内容。

    -----------------------------------------

    解释:

    ①运行上述代码的结果(使用TDM-GCC 4.9.2编译):1.#INF00e+000

    ②float类型的数以指数和尾数部分来储存:例如以浮点形式存储π,内存中大致如下[+][ .314159 ][ 1 ],即[符号][尾数][指数]

    通常情况下,上溢是在对数进行加法时发生的,下溢是在对数进行除法时发生的。

  • 相关阅读:
    基础知识漫谈(5):应用面向对象来分析“语言”
    【线段树】BZOJ2752: [HAOI2012]高速公路(road)
    【树状数组】BZOJ3132 上帝造题的七分钟
    【AC自动机】Lougu P3796
    【Splay】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)
    【fhq Treap】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)
    【可持久化线段树】POJ2104 查询区间第k小值
    【RMQ】洛谷P3379 RMQ求LCA
    【倍增】洛谷P3379 倍增求LCA
    【网络流】POJ1273 Drainage Ditches
  • 原文地址:https://www.cnblogs.com/mrblug/p/5706996.html
Copyright © 2020-2023  润新知