2

For the following code

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

The compiler is giving me these warnings.

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

Why is the compiler giving these warnings when 64 > 60?

4

2 回答 2

9

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

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

更好的写法是return f * 0x1p-60f;. 0x1p-60f是一个float值为 2 –60的常数。

于 2013-04-18T14:04:24.460 回答
3

在您的代码中,实际上存在与 int64_t 无关的错误。在(1 << 60)表达式中160都被认为是 int (通常是 32 位)。你应该使用修饰符LL。像(1LL << 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));

这里的问题至少在我所在的领域并非所有编译器都正确实现了这些宏(这是可能的证明之一)。但是主流编译器应该很高兴。至少我不建议混合%lld甚至1LL在 GCC 中(你可以尝试,至少 GCC 4.6.3 抱怨这种混合)。

于 2013-04-18T14:06:17.870 回答