printf 64位类型说明符问题

3

我在使用msdev 2010时遇到了一些__int64类型的奇怪行为。是否有人能够告诉我发生了什么? 我猜这里有两个问题,首先是如何显示64位整数,其次是行为-即为什么看起来像__int64实际上是32位整数...

#include <stdio.h>

int main()
{
  int vl_idx;
  unsigned __int64 vl_64;
  unsigned __int64 vl_64_test;

  for (vl_idx = 0; vl_idx < 64; vl_idx++)
  {
    vl_64 = 1 << vl_idx;
    printf ("vl_64 (%d) = %I64u\n", vl_idx, vl_64);
    printf ("vl_64 (%d) = %llu\n", vl_idx, vl_64);
    printf ("vl_64 (%d) = %lu\n", vl_idx, vl_64);
  }
  vl_64_test = 1 << 31;
  if (vl_64 > vl_64_test)
     printf ("greater\n");
  if (vl_64 == vl_64_test)
     printf ("equal\n");
  if (vl_64 < vl_64_test)
     printf ("less\n");

  return 0;
}

前30次迭代的输出结果如预期:

vl_64 (0) = 1
vl_64 (0) = 1
vl_64 (0) = 1
vl_64 (1) = 2
vl_64 (1) = 2
vl_64 (1) = 2
...
vl_64 (30) = 1073741824
vl_64 (30) = 1073741824
vl_64 (30) = 1073741824
vl_64 (31) = 18446744071562067968
vl_64 (31) = 18446744071562067968
vl_64 (31) = 2147483648
vl_64 (32) = 1
vl_64 (32) = 1
vl_64 (32) = 1
vl_64 (33) = 2
vl_64 (33) = 2
vl_64 (33) = 2
...
vl_64 (62) = 1073741824
vl_64 (62) = 1073741824
vl_64 (62) = 1073741824
vl_64 (63) = 18446744071562067968
vl_64 (63) = 18446744071562067968
vl_64 (63) = 2147483648
equal

但是,在第32次迭代时,事情发生了“溢出”。这可能只是一个显示问题,但结尾处的比较表明情况并非如此。

这是使用msdev 2010 cl(64位版本)编译,并在64位Windows操作系统上运行(具有64位CPU)。有什么建议可以解释为什么比较会认为1<<31 == 1<<63?

感谢任何建议,

Jim

1个回答

1

在处理比int更宽的任何内容时,您需要小心整数字面量,例如,您需要更改:

vl_64 = 1 << vl_idx;

至:

vl_64 = 1LLU << vl_idx;

否则,右侧将首先被评估为一个int表达式,然后被隐式转换为一个无符号的64位结果。

是的,就是这样。谢谢你。微软似乎不理解1LLU,但如果我将1强制转换为(unsigned __int64),它可以达到同样的效果 - 输出结果也符合预期。 - Jim Edwards

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接