一个C语言中的 位运算问题 (求高手解答)
近期在写一个简单程序的时候,遇到了“奇怪”的现象:
VC++6.0上结果与预期相符,而GCC下看到的结果很奇怪。
示例程序如下:
#include <stdio.h>
#include <stdlib.h>
/*
How to store val to assgined bit in a data ?
1. clear the assigned position in the original value
2. get the value to fill in :
just set the bit (from the start bit to end bit )
of the value to store , and clear other bits
beyond range "from start bit to end bit "
3. "OR" operation of the result in 1,2
For clear operation, we need a mask , other bits are 1,
start bit to end bit are all 0.
*/
unsigned short store_bit_field(unsigned short original_val,
unsigned short val_to_store,
unsigned int start_bit,
unsigned int end_bit)
{
unsigned short mask = ~0;
unsigned short clear_orig = 0;
unsigned short val_to_fill = 0;
// int orig_bit_num = (sizeof(original_val) * 8 );
// unsigned short u_mask = 0;
if(start_bit > orig_bit_num - 1)
{
printf("invalid start bit pos , return 0 \n");
return 0;
}
if(end_bit > orig_bit_num - 1)
{
end_bit = orig_bit_num - 1 ;
}
printf("ori_bit_num = %d ,start_bit = %d , end_bit = %d \n",
orig_bit_num,start_bit,end_bit);
// printf("original_val = %x\n",original_val);
// method 1:
// mask = (mask << start_bit) & (~(mask << (end_bit+1)));
// if end_bit + 1 == 16, (1 << (end_bit + 1)) will be 0 (unsigned)
// method 2 :
// mask = (1 << (end_bit + 1)) - ((1 << start_bit) - 1) - 1;
// method 3 :
mask = (mask << (start_bit)) - (mask << (end_bit + 1));
printf("mask is %x \n",mask);
//u_mask = ~mask;
// printf(" u_mask = %x \n", u_mask);
clear_orig = (original_val & (~mask));
printf(" orignal value after bits are cleared is %x \n",
clear_orig);
val_to_fill = (val_to_store << start_bit) & mask;
printf(" value to store after other bits are cleared is %x \n",
val_to_fill);
return (val_to_fill | clear_orig);
}
int main()
{
unsigned short orig_val;
unsigned short val_to_set;
unsigned int start_bit;
unsigned int end_bit;
printf(" please input original value : ");
scanf("%x",&orig_val);
printf(" please input value to set : ");
scanf("%x",&val_to_set);
printf("please input start bit & end bit pos : ");
scanf("%d%d",&start_bit,&end_bit);
// printf("orig_val = %x , val_to_set = %x\n",orig_val,val_to_set);
printf("value is set , now original changed to %x \n",
store_bit_field(orig_val,val_to_set,start_bit,end_bit));
system("PAUSE");
return 0;
}
GCC 运行结果如下:
please input original value : ffff
please input value to set : 123
please input start bit & end bit pos : 4 15
ori_bit_num = 16 ,start_bit = 4 , end_bit = 15
mask is fff0
orignal value after bits are cleared is 0
value to store after other bits are cleared is 1230
value is set , now original changed to 1230
请按任意键继续. . .
而VC++运行结果为:
please input original value : ffff
please input value to set : 123
please input start bit & end bit pos : 4 15
ori_bit_num = 16 ,start_bit = 4 , end_bit = 15
mask is fff0
orignal value after bits are cleared is f
value to store after other bits are cleared is 123f
value is set , now original changed to 123f
请按任意键继续. . .
为什么会有这样的差别呢?
当加入上述红色标记的debug信息后,发现orig_val为0,但我们实际输入的是
0xffff啊? 为什么GCC下会变成0,而VC++ 6.0下看到的是0XFFFF呢?
我们看到,输入的orig_val是%x的,这样的话可能导致读入的高两字节(全0),
难道涉及到大端,小端的问题了? 可是细想,不应该啊? 0X123拿打印出来是对
的啊。
不管了,将之前unsigned short 的%x全部改成%hx (输入,输出格式),最终发现
GCC下的结果为0x123f,如预期。
疑问: 到底是什么原因,导致VC++6.0 和 GCC下得到的结果不一致呢?
求各位高手不吝赐教,多谢多谢!!
[解决办法]
我擦 你这个排版让我看的实在单疼