zoukankan      html  css  js  c++  java
  • 关于C语言中的无符号数和有符号数

    无符号数和有符号数是不能进行比较运算的,否则可能会出现意想不到的错误,且极难检查出来!
    首先肯几个例子(假设在32位的机器上):
    1         10 == 0U
    2         2-1 < 0U (注: 0是无符号的)
    3         32147483647U > -2147483647 - 1
    4         42147483647 > (int2147483648U
    结果如下:
    1         11
    2         20 *
    3         30 *
    4         41 *
    从结果中可以看出,2 3 4都不是我们想像中的结果。在C语言中,当一个无符号数和一个有符号数进行比较运算时,有符号数会被隐含的转换成无符号数,并假设这两个数都是非负数,然后进行比较运算。当把一个有符号数转换成无符号数时,其底层的二进制表示没有改变,仅仅是对其进行了不同的解释。这样,由于这两个原因就会出现上面的结果。
    首先分析一下2:
    -1的二进制补码表示是32个1。而0U的二进制补码表示是32个0.在比较的时候,-1被当做无符号数,也就是把32个1当做无符号数和32个0的无符号数比较,显然,32个1要大于32个0.所以,2的结果是1.
    再看看3,-2147483647的二进制补码表示是1000 0000 0000 0000 0000 0000 0000 0000, -1的补码表示是32个1,两个相加,也就是补码异或,得到0111 1111 1111 1111 1111 1111 1111 1111,这个结果是溢出的。由于前一个的操作数是无符号数,因此,前面的计算结果被当做无符号数来处理,因此,这两个数是相等的。所以结果是0.对于4,2147483648U被转换成有符号数是-1,所以4的结果是1.
    从上面可以看出,无符号数和有符号数在进行比较的时候,如果数值在边界上,则很容易出错。
    看下面的一段程序:
     1 float sum(float a[], unsigned int len)
     2 {
     3     int i;
     4     float r = 0.0;
     5     for (i = 0; i <= len - 1++i)
     6     {
     7         r += a[i];
     8     }
     9     return r;
    10 }
    如果len为0,那么这段代码将不会返回0.0。而是段错误。

    另外,当在无符号数和有符号数之间进行类型转换时,不同的转换顺序会得到不同的结果。如:
    1 
    2 unsigned x = 0xFFFF;
    3 (int) ((word << 24>> 24);
    4 ((int) word << 24>> 24;
            第一个表达式的结果是0xFF,而第二个是0xFFFFFFFF.原因是第一个表达式的右移运算高位补0,而第二个右移运算高位补1.

    测试代码:
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 float sum(float a[], unsigned int len)
     4 {
     5     int i;
     6     float r = 0.0;
     7     for(i = 0; i <= len - 1++i)
     8     {
     9         r += a[i];
    10     }
    11     
    12     return r;
    13 }
    14 
    15 int main()
    16 {
    17     printf("-1 < 0U : %s\n", (-1 < 0U? "true" : "false");
    18     printf("2147483647U > -2147483647 - 1 : %s\n", ( 2147483647U > -2147483647 - 1? "true" : "false");
    19     printf("2147483647 > (int)2147483648U : %s\n", ( 2147483647 > (int)2147483648U? "true" : "false");
    20     
    21     unsigned w = 0xFFFF;
    22     printf("(int) ((w << 24) >> 24) = %x\n", (int) ((w << 24>> 24));
    23     printf("((int)(w << 24)) >> 24 = %x\n", ((int)(w << 24)) >> 24);
    24 
    25     float a[1];
    26     printf("sum %f\n", sum(a, 0));
    27     return 0;
    28 }
    运行结果:
    1 hcy@hcy-desktop:~$ ./a.out 
    2 -1 < 0U : false
    3 2147483647U > -2147483647 - 1 : false
    4 2147483647 > (int)2147483648U : true
    5 (int) ((w << 24>> 24= ff
    6 ((int)(w << 24)) >> 24 = ffffffff
    7 段错误
  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/kernel_hcy/p/1640152.html
Copyright © 2011-2022 走看看