int64_t的宽度是64位吗?

时间:2013-04-18 14:01:29

标签: c gcc x86

以下代码

static inline float fix2float(int64_t f)
{
    return (float)f / (1 << 60); // <-- error here
}

编译器正在给我这些警告。

warning: left shift count >= width of type
warning: division by zero

为什么编译器在64&gt;时发出这些警告? 60?

2 个答案:

答案 0 :(得分:9)

1不是C实现中的64位数字。它是int,可能是32位。

编译器不查看表达式并看到涉及int64_t,因此其他算法应使用64位。它从它们的部分构建表达式。在(1 << 60)部分中,编译器识别一个并给它一个int类型,因为这就是C规则对简单常量值所说的(对于十六进制表示法有后缀,后缀,和大的价值观)。因此,1 << 60尝试将int移位60位。由于系统上的int只有32位,编译器会发出警告。

更好的方法是return f * 0x1p-60f;0x1p-60f是一个float常量,值为2 -60

答案 1 :(得分:3)

在您的代码中,存在与int64_t实际上没有关系的错误。在(1 << 60)表达式中,160都被视为int(通常为32位)。您应该使用修饰符LL。 像(1LL&lt;&lt; 60)。

#include <stdio.h>

int main()
{
    printf("%llx\n", (1LL << 60));
    return 0;
}

顺便提一下,请注意printf()格式。 int64_t实际上是long long(至少在大多数情况下)。

更新:有社区声音建议使用稍微不同的方法:

printf("%" PRIx64 "\n", (UINT64_C(1) << 60));

这里的问题至少在我的领域并非所有编译器都能正确实现这些宏(这里是one of possible proofs)。但主流编译器应该感到高兴。至少我不建议在GCC中混合使用%lld1LL(你可以尝试,至少GCC 4.6.3抱怨这种混合)。