unsigned int(32bit)to unsigned long long(64bit)

时间:2013-07-31 20:00:06

标签: c unsigned-integer unsigned-long-long-int

在下面的代码中,我将0xffffffff乘以unsigned int(32位),并将其存储在unsigned long long(64位)中。为什么我得不到8589934588的实际输出。相反,我得到4294967294。     提前致谢。     OUTPUT:     sizeof i = 4     尺寸J = 8     2xi = 4294967292

/* Code starts here */
#include <stdio.h>
#include <stdlib.h>

int main (void) 
{
    unsigned int i=4294967294;
    unsigned long long j=i*2;
    printf("Sizeof i=%d\n", sizeof(i));
    printf("Sizeof J=%d\n", sizeof(j));
    printf("2xi=%llu\n", j);

    return 0;
}

3 个答案:

答案 0 :(得分:5)

这是因为i*2是整数乘法。即使你将它存储在long long中,你仍然在进行整数运算,这会导致溢出。

以下代码有效,因为我们将其提升至long long乘以

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
  unsigned int i=4294967294;
  unsigned long long j=((unsigned long long)i)*2;
  printf("Sizeof i=%d\n", sizeof(i));
  printf("Sizeof J=%d\n", sizeof(j));
  printf("2xi=%llu\n", j);

  return 0;
}

结果:

bash-4.1$ gcc long.c
bash-4.1$ ./a.out
Sizeof i=4
Sizeof J=8
2xi=8589934588

答案 1 :(得分:3)

i*2对于将unsigned long long分配给i的事实一无所知 - 因为unsigned int2intunsigned int乘法是使用2类型执行的,这会产生你得到的结果。

您可以通过unsigned long long i字面值来解决问题,将unsigned long long提升为i进行乘法,或将unsigned long long强制转换为{{ 1}}在乘法之前,它具有相同的效果:

unsigned long long j=i*2ULL;
/* or */
unsigned long long j=((unsigned long long)i)*2;

一般来说,请记住:在C中,赋值/初始化的目标不影响如何计算右边的表达式 - 所涉及的类型仅由操作数的类型决定。

答案 2 :(得分:2)

由于iunsigned int2int,并且会被提升为unsigned int,因此操作将会回滚。一种解决方案是将i投射到unsigned long long

unsigned long long j = ((unsigned long long)i)*2 ;

draft C11 standard的相关部分位于6.2.5/9

  

涉及无符号操作数的计算永远不会溢出,   因为无法用结果无符号整数类型表示的结果是   减少模数可以是最大值的数字   由结果类型表示。