从__int64和int的溢出来探讨大小端模式。

本文探讨了在C语言中使用%d与%I64d格式符输出64位整数(long long类型)时的行为差异,通过具体实例展示了不同类型变量存储64位整数值时的截断效果,并分析了小端模式下数据存储的特点。

类型long long

即可存储64位的类型。

用printf函数输出时,类型应为%I64d。

如果用%d输出会怎么样呢?

如下:


long long twoToPowerOf( int n )
{
 /*int result = 1;
 int i=0;
 for ( i=0 ; i<power ; i++ )
 {
 result=result<<1;
 }
 return result;*/

 long long result;
 long long x;
 x=2;
 if (n == 0) 
 { 
  return 1; 
 } 
 else 
 { 
  while ((n & 1) == 0) 
  { 
   n >>= 1; 
   x *= x; 
  } 
 } 
 result = x; 
 n >>= 1; 
 while (n != 0) 
 {    
  x *= x; 
  if ((n & 1) != 0) 
   result *= x; 
  n >>= 1; 
 } 
 return result;
}

main()
{
__int64 a;

int b;

a=twoToPowerOf(35)+1;
b=a;
printf("%d\n",a);
printf("%d\n",b);
printf("%I64d\n",a);

}

 

结果如图

 

简单的解释一下吧。twoToPowerOf(35)输出的为2的35次方幂。用int类型存储就越界了。然后但是vs2008并没有报错

。怎么存取的呢?由程序分析得知,int类型的b存储的是__int64类型的a的低32位。所以,b输入为1。注意,a的值为2的35次方+1。

为什么从低32位截取呢?笔者才疏学浅,猜测为与大小端模式有关。小端模式:低地址存低位。所以溢出的为高位。这样低位就被存下来了。

也许这是继用union结构体外的检测大小端模式的另一种方法。

 

我们再来思考一下。将main()换成如下函数:

main()
{
__int64 a;
long long m;
int i;
char b;
int c;
a=twoToPowerOf(35)+twoToPowerOf(9)+twoToPowerOf(7)+twoToPowerOf(63);
b=a;
m=a;
c=a;
printf("a二进制表示如下:\n");
printf("(注意:低位在左,高位在右)\n");
for (i=0;i<64;i++)
{
 if (m&1!=0)
 {
  printf("1");
 }
 else
 {
  printf("0");
 }
 m=m>>1;
 

}
printf("\n");
printf("%d\n",c);
printf("%d\n",b);
printf("%I64d\n",a);

}

结果如下:

这次难度好像增加了,我们分析一下,a的二进制为如上图。

然后,char类型的b和int类型的c对__int64类型的a进行的截取。b截了8位二进制表达为:10000000。十进制为-128。为什么是-128请参考(http://blog.youkuaiyun.com/chenhuijie666/article/details/7513455),c截了32位为二进制位为1010000000。十进制为640。注意c的最左位为0哦。他是32位的啊。右侧省略了好多个0呢。为什么a为这个数呢?同样参考(http://blog.youkuaiyun.com/chenhuijie666/article/details/7513455)。至于short类型的截取。有空再更新吧。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值