我正在开发一个嵌入式项目,当时我遇到了一些我认为很奇怪的行为。我设法在键盘上重现它(见下文)以进行确认,但我的机器上没有任何其他 C 编译器可以对其进行尝试。
场景:我有一个#define
对于 32 位整数可以容纳的最大负值,然后我尝试使用它与浮点值进行比较,如下所示:
#define INT32_MIN (-2147483648L)
void main()
{
float myNumber = 0.0f;
if(myNumber > INT32_MIN)
{
printf("Everything is OK");
}
else
{
printf("The universe is broken!!");
}
}
键盘链接:http://codepad.org/cBneMZL5 http://codepad.org/cBneMZL5
对我来说,这段代码看起来应该可以正常工作,但令我惊讶的是它打印出来了The universe is broken!!
.
此代码隐式转换INT32_MIN
to a float
,但事实证明这会导致浮点值2147483648.0
(积极!),即使浮点类型完全能够表示-2147483648.0
.
有谁对这种行为的原因有任何见解吗?
代码解决方案:正如 Steve Jessop 在他的回答中提到的,limits.h
and stdint.h
包含正确的(工作)int
range define
已经,所以我现在使用这些而不是我自己的#define
问题/解决方案说明摘要:鉴于答案和讨论,我认为这是对正在发生的事情的一个很好的总结(注意:仍然阅读答案/评论,因为它们提供了更详细的解释):
- 我使用的是 32 位 C89 编译器
long
s,因此任何大于的值LONG_MAX
且小于或等于ULONG_MAX
接下来是L
postfix 有一种类型unsigned long
-
(-2147483648L)
实际上是一元-
on an unsigned long
(见上一点)值:-(2147483648L)
。此否定操作将值“包裹”为unsigned long
的价值2147483648
(因为 32 位unsigned long
s 有范围0
- 4294967295
).
- This
unsigned long
number looks就像预期的负面结果一样int
当它被打印为一个值时int
或传递给一个函数,因为它首先被转换为int
,这超出了范围2147483648
大约到-2147483648
(因为 32 位int
s 的范围为 -2147483648 到 2147483647)
- 演员阵容
float
然而,正在使用实际的unsigned long
value 2147483648
进行转换,得到浮点值2147483648.0
.
Replace
#define INT32_MIN (-2147483648L)
with
#define INT32_MIN (-2147483647 - 1)
-2147483648
被编译器解释为否定2147483648
,这会导致溢出int
。所以你应该写(-2147483647 - 1)
反而。
这就是全部C89
标准虽然。请参阅 Steve Jessop 的回答C99
.
Also long
在 32 位计算机上通常为 32 位,在 64 位计算机上通常为 64 位。int
事情就在这里完成。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)