MENU

自动类型转换之数值溢出 | C语言

June 16, 2019 • 我爱学习

主要内容:

  • 不同类型间数据赋值是否安全?
  • 为什么会数值溢出?为什么会溢出?有什么危害

不同那个数据域间赋值安全吗?

  • 取值范围大的类型 -> 取值范围小的类型时,通常是不安全的。

为什么会发生数值溢出?

  • 任何一种类型都只能用有限的位数存储一定范围的数据,当向变量赋的值超过了其本身类型所能储存的范围时,就会发生数值溢出。

整数数值溢出

  • 有符号整数和无符号整数的区别:有符号整数的最高位被标记为符号位。为0表示正数,为1表示负数。
  • 当一个有符号整型数值运算超过了其数值范围的上界,导致进位到达了符号位,使得符号位改变 (这里假设符号位由0变到1, 0->1 ) ,从而输出结果从正数变为负数。
上溢出
  • 什么是上溢出:

    1. | 一个数值运算结果 | > | 类型能表示的最大数 |
    2. 进位超过最高位而发生进位丢失(无符号型)
    3. 进位达到最高位而改变符号位(有符号型}

      • 对于无符号整型来说,当我们将它的最大值加1操作后,会使这个数变成这个类型所能表达的最小值。

类似于钟表一样。当指针指向23点时,再加1就会变成0点

  • 假设我们有一个数为32767 (int型的最大值,unsigned int型的一个普通值),当我们对它进行+1操作时,假设这个数为无符号整数的话。此时它的数值大小为32768。
  • 但是如果我们把它解释为有符号数时,由于最高位被解释为符号位,此时符号位由0变到1,所以这个数被解释为负数,而此时这个数正是有符号整型所能表示的最小值的二进制形式。 (也可以同样理解为钟表模型)

数值上溢出的两个例子

下溢出
  • 我们先来看一个例子:

下溢出

  • 这个例子中,是两个无符号短整型数据做减法运算,在这个情况下,当被减数小于减数时,也会发生溢出。
  • 当这两个数进行减法运算时,由于0减1不够减,要向前借位,借位一直向前进行,当借位超过了最高位 (也就是例子中的情况) ,得到以此结果 (按照有符号位整数解释的话,此时的值为-2),但因为我们此时将它解释为无符号整型,虽然它的最高位为1,仍然要将它作为数据来处理。

    因此对于无符号数,不能用a-b<0 代替 a < b

浮点数的数值溢出

  • 在讲这个内容之前,我们要理解浮点数的储存原理
  • 与整型数据的溢出不同,浮点数既可以出现上溢出也可以出现下溢出。这是由浮点数的储存原理所决定的。
  • 浮点数的储存是以阶码和尾数来储存的。因此浮点数的储存并不是连续的。如下图:

浮点数的数据范围

  • 所以浮点数的上溢出:

    • | 浮点数运算结果 | > |类型所能表示的最大数 |
  • 下溢出:

    • | 浮点数运算结果 | < |类型所能表示的最大数 |
  • 当浮点数发生下溢出时,系统会将运算结果处理成为机器0.因为这个数已经无限的接近于0,并且精度要大于浮点数所能表示的最大精度。
Last Modified: September 8, 2021