unsigned long 乘以 float 会变成负数吗?
Can an unsigned long become negative when multiplied by a float?
标题可能是 ill-chosen,但我找不到很好的 one-line 这个问题的摘要。我的问题是我无法理解我的编译器在做什么,我想知道我是否在编译器中发现了一个错误……或者我对 C 语言的理解。
我的理解是:
- 1UL == ULONG_MAX
,这是安全的,因为无符号数的溢出行为已明确定义
- 乘积
(- 1UL) * 1.0f
涉及左操作数向浮点数的转换,此转换保留值(即ULONG_MAX
)除舍入误差
到目前为止我的编译器同意,除非 1UL
来自变量。这是我的测试程序,其输出为注释:
#include <stdio.h>
int main(void)
{
unsigned long one = 1;
unsigned long minus_one = - one;
printf("%lu\n", - one); // 18446744073709551615
printf("%g\n", minus_one * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0); // 1.84467e+19
printf("%g\n", (- 1UL) * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0f); // -1
return 0;
}
我无法理解最后的输出。我尝试了各种优化级别和各种语言标准(C90、C99 和 C11),结果相同。有人知道吗?
环境:gcc 4.8.1/UbuntuLinux14.04/x86-64 (I32LP64)
编辑:我刚刚注意到我的问题可能与 combination of unary minus and float conversion.
重复
这似乎是 gcc 4.8 中的错误。我在 4.8 中的行为与您相同,但 gcc 4.9 和 clang 显示了更正的行为。
标题可能是 ill-chosen,但我找不到很好的 one-line 这个问题的摘要。我的问题是我无法理解我的编译器在做什么,我想知道我是否在编译器中发现了一个错误……或者我对 C 语言的理解。
我的理解是:
- 1UL == ULONG_MAX
,这是安全的,因为无符号数的溢出行为已明确定义- 乘积
(- 1UL) * 1.0f
涉及左操作数向浮点数的转换,此转换保留值(即ULONG_MAX
)除舍入误差
到目前为止我的编译器同意,除非 1UL
来自变量。这是我的测试程序,其输出为注释:
#include <stdio.h>
int main(void)
{
unsigned long one = 1;
unsigned long minus_one = - one;
printf("%lu\n", - one); // 18446744073709551615
printf("%g\n", minus_one * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0); // 1.84467e+19
printf("%g\n", (- 1UL) * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0f); // -1
return 0;
}
我无法理解最后的输出。我尝试了各种优化级别和各种语言标准(C90、C99 和 C11),结果相同。有人知道吗?
环境:gcc 4.8.1/UbuntuLinux14.04/x86-64 (I32LP64)
编辑:我刚刚注意到我的问题可能与 combination of unary minus and float conversion.
重复这似乎是 gcc 4.8 中的错误。我在 4.8 中的行为与您相同,但 gcc 4.9 和 clang 显示了更正的行为。