【问题标题】:unsigned int(32bit) to unsigned long long (64bit)unsigned int(32 位)到 unsigned long long(64 位)
【发布时间】:2013-08-01 12:49:27
【问题描述】:

在下面的代码中,我将 0xffffffff 乘以 2 得到 unsigned int(32 位)并将其存储在 unsigned long long(64 位)中。为什么我没有得到8589934588 的实际输出。相反,我得到4294967294。 提前致谢。 输出: 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;
}

【问题讨论】:

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


    【解决方案1】:

    这是因为i*2 是整数相乘。即使您将其存储在long long 中,您仍在进行整数数学运算,这会导致溢出。

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

    #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
    

    【讨论】:

    • 请记住signed overflow 是未定义的行为,但无符号溢出只是换行。
    【解决方案2】:

    由于iunsigned int 并且2int 并且将被提升为unsigned int,因此操作将只是环绕。一种解决方案是将i 转换为unsigned long long

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

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

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

    【讨论】:

      【解决方案3】:

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

      您可以通过将2 设为unsigned long long 文字来解决此问题,这会将i 提升为unsigned long long 以进行乘法运算,或者在乘法之前将i 转换为unsigned long long,具有相同的效果:

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

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

      【讨论】:

        猜你喜欢
        • 2016-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-27
        • 1970-01-01
        • 2016-12-20
        相关资源
        最近更新 更多