今天在看C语言缺陷和陷阱的时候,看到位移
也就是右移过程中空出来的位置
unsigned 使用0填充
signed 可能使用0填充和符号位填充, 如果关心填充位请使用unsigned,
但是我在另外一本书中看到为了避免可能的转换问题尽量使用signed,除非必须使用unsigned,也许这就是必须的情况吧
而最大的可以位移数为 0到(位数-1)
比如int 就是 0-31是合法的 32 和 -1 都是不合法的,
使用GNU C
实验中,都报错
test.c:25:3: warning: right shift count is negative [enabled by default]
a>>39;
确实如此,但是我们如果一次移动一位移动39次呢,这样就合法了。这里实验一下右移
左移始终用0填充,否则结果不正确了。但给出左移动的最大表示数 和程序
最后如下
.....
16777216
16777216
33554432
33554432
67108864
67108864
134217728
134217728
268435456
268435456
536870912
536870912
1073741824
1073741824
-2147483648 --signed
2147483648 --unsigned
0
0
如果在移动都全部是0了最高位已经没有了。
下面是右移动主要看看是否使用符号位填充
程序:
Hardware watchpoint 2: i==30
Old value = 0
New value = 1
0x000000000040057e in main () at test.c:20
20 for(i=0;i<50;i++)
(gdb) p &a
$1 = (int *) 0x7fffffffe9f4
(gdb) p &b
$2 = (unsigned int *) 0x7fffffffe9f8
(gdb) x/4bx &a
0x7fffffffe9f4: 0xfe 0xff 0xff 0xff
(gdb) x/4bx &b
0x7fffffffe9f8: 0x02 0x00 0x00 0x00
(gdb)
可以看到有符号位的a确实使用了符号位进行了填充,因为是负数全部是符号位
0x7fffffffe9f4: 0xfe 0xff 0xff 0xff
输出结果最后为
......
-32
32
-16
16
-8
8
-4
4
-2
2
-1
1
-1
0
也就是右移过程中空出来的位置
unsigned 使用0填充
signed 可能使用0填充和符号位填充, 如果关心填充位请使用unsigned,
但是我在另外一本书中看到为了避免可能的转换问题尽量使用signed,除非必须使用unsigned,也许这就是必须的情况吧
而最大的可以位移数为 0到(位数-1)
比如int 就是 0-31是合法的 32 和 -1 都是不合法的,
使用GNU C
实验中,都报错
test.c:25:3: warning: right shift count is negative [enabled by default]
a>>39;
确实如此,但是我们如果一次移动一位移动39次呢,这样就合法了。这里实验一下右移
左移始终用0填充,否则结果不正确了。但给出左移动的最大表示数 和程序
点击(此处)折叠或打开
- #include<stdio.h>
-
-
-
-
- int main(void)
- {
- int a=1;
- unsigned int b = 1;
- int i;
-
-
- for(i=0;i<50;i++)
- {
-
- printf("%d\n",a);
- printf("%u\n",b);
- a<<=1;
- b<<=1;
- }
- }
最后如下
.....
16777216
16777216
33554432
33554432
67108864
67108864
134217728
134217728
268435456
268435456
536870912
536870912
1073741824
1073741824
-2147483648 --signed
2147483648 --unsigned
0
0
如果在移动都全部是0了最高位已经没有了。
下面是右移动主要看看是否使用符号位填充
程序:
点击(此处)折叠或打开
- #include<stdio.h>
-
-
-
-
- int main(void)
- {
- int a=-2147483648;
- unsigned int b = 2147483648;
- int i;
-
-
- for(i=0;i<50;i++)
- {
-
- printf("%d\n",a);
- printf("%u\n",b);
- a>>=1;
- b>>=1;
- }
- }
Hardware watchpoint 2: i==30
Old value = 0
New value = 1
0x000000000040057e in main () at test.c:20
20 for(i=0;i<50;i++)
(gdb) p &a
$1 = (int *) 0x7fffffffe9f4
(gdb) p &b
$2 = (unsigned int *) 0x7fffffffe9f8
(gdb) x/4bx &a
0x7fffffffe9f4: 0xfe 0xff 0xff 0xff
(gdb) x/4bx &b
0x7fffffffe9f8: 0x02 0x00 0x00 0x00
(gdb)
可以看到有符号位的a确实使用了符号位进行了填充,因为是负数全部是符号位
0x7fffffffe9f4: 0xfe 0xff 0xff 0xff
输出结果最后为
......
-32
32
-16
16
-8
8
-4
4
-2
2
-1
1
-1
0