【问题标题】:Impossible to print a long long integer in C无法在 C 中打印长整数
【发布时间】:2015-03-18 16:45:40
【问题描述】:

我知道有很多关于这个主题的主题,但没有一个能帮助我解决我的问题。 我在 Code::Blocks 上工作(在“属性>项目构建选项>编译器设置>其他选项”中使用选项 -std=c99)并且以下代码没有给出预期的输出:

long long val=1<<33;
printf("value: %llu",val);

实际上我在终端中获得了“值:0”。 我该如何解决这个问题?

当我写 30 而不是 33(所以 val 是一个整数)时,我得到了正确的答案。我也试过 %lld 但这没有帮助。

【问题讨论】:

  • 你的编译器没有警告过吗?

标签: c printf long-long


【解决方案1】:

由于您没有以任何方式限定文字 1 和 33,1&lt;&lt;33 将具有 int 作为其类型。如果int 是 32 位(在针对 64 位的编译器上很常见),那么这个表达式将产生 未定义的行为

一个简单的解决方法是写1LL &lt;&lt; 331LLlong long,33 也将被提升为该类型。 C++ 标准保证long long至少 64 位。

虽然我更喜欢static_cast&lt;std::int64_t&gt;(1) &lt;&lt; 33

【讨论】:

  • &lt;&lt;&gt;&gt; 的操作数不进行通常的算术转换。在1LL &lt;&lt; 33 中将33 提升为long long 是K&R C 的事情(事实上K&R C 没有long long)。
【解决方案2】:

1&lt;&lt;33 将为 32 位 int 调用未定义的行为。

C11:6.5.7 移位运算符:

E1 &lt;&lt; E2 的结果是E1 左移E2 位位置;空出的位用零填充。如果E1 具有无符号类型,则结果的值为E1 × 2E2,以比结果类型中可表示的最大值多1 为模减少。 如果E1 具有带符号类型和非负值,并且E1 × 2E2 在结果类型中是可表示的,那么这就是结果值;否则,行为未定义

【讨论】:

    【解决方案3】:

    1&lt;&lt;33 的移位不是在 long long 类型上完成的。 1 在这里是int;将其转换为 long long 或以 LL 为后缀,例如 1LL &lt;&lt; 33

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多