int64_t的宽度是64位吗?
对于以下代码
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> 60时,为什么编译器会发出这些警告?
1
在C实现中不是64位数字。 它是一个int
,可能是32位。
编译器不会查看表达式并看到有涉及的int64_t
,因此其他算法应该使用64位。 它从它们的部分构建表达式。 在部分(1 << 60)
,编译器识别一个并给它一个int
类型,因为这就是C规则对简单常量值所说的(hex表示法,后缀和大值的附加规则) )。 因此, 1 << 60
试图将int
移位60位。 由于系统上的int
只有32位,编译器会发出警告。
写这个的更好方法是return f * 0x1p-60f;
。 0x1p-60f
是一个float
常量,值为2 -60 。
在您的代码中,存在与int64_t实际上没有关系的错误。 在(1 << 60)
表达式中, 1
和60
都被认为是int(通常是32位)。 您应该使用修饰符LL
。 像(1LL << 60)。
#include int main() { printf("%llx\n", (1LL << 60)); return 0; }
请注意printf()
格式。 int64_t
实际上long long
(至少在大多数情况下)。
更新:有社区声音,建议使用一些不同的方法:
printf("%" PRIx64 "\n", (UINT64_C(1) << 60));
这里的问题至少在我的领域并非所有编译器都能正确实现这些宏(这是可能的certificate之一 )。 但主流编译器应该感到高兴。 至少我不建议在GCC中混合%lld
和1LL
(你可以试试,至少GCC 4.6.3抱怨这种混合)。