将负双精度转换为无符号整数的行为是否在 C 标准中定义?ARM 与 x86 上的不同行为 [英] Is the behaviour of casting a negative double to unsigned int defined in the C standard? Different behaviour on ARM vs. x86
问题描述
我有在不同平台上运行的代码,似乎得到不同的结果.我正在寻找适当的解释.
I have code that runs on different platforms that seems to get different results. I am looking for a proper explanation.
我希望 unsigned
的转换对 float
或 double
与 int
的工作方式相同1.
I expected casting to unsigned
to work the same for float
or double
as for int
1.
Windows:
double dbl = -123.45;
int d_cast = (unsigned int)dbl;
// d_cast == -123
WinCE (ARM):
double dbl = -123.45;
int d_cast = (unsigned int)dbl;
// d_cast == 0
感谢您指出正确的方向.
Thanks for pointing in the right direction.
修复解决方法
fix workaround
double dbl = -123.45;
int d_cast = (unsigned)(int)dbl;
// d_cast == -123
// works on both.
<小时>
脚注 1:编者注:将超出范围的 unsigned
值转换为像 int
这样的有符号类型是实现定义(不是不明确的).C17 § 6.3.1.3 - 3.
Footnote 1: Editor's note: converting an out-of-range unsigned
value to a signed type like int
is implementation defined (not undefined). C17 § 6.3.1.3 - 3.
因此,对于 (unsigned)dbl
最终在某些特定实现上是一个巨大的正值的情况,标准也没有确定对 d_cast
的分配.(该执行路径包含 UB,因此理论上 ISO C 已经不在了).实际上,编译器在正常的 2 的补码机器上执行我们所期望的操作,并保持位模式不变.
So the assignment to d_cast
is also not nailed down by the standard for cases where (unsigned)dbl
ends up being a huge positive value on some particular implementation. (That path of execution contains UB so ISO C is already out the window in theory). In practice compilers do what we expect on normal 2's complement machines and leave the bit-pattern unchanged.
推荐答案
否
<小时>此转换未定义,因此不可移植.
No
This conversion is undefined and therefore not portable.
C99/C11 6.3.1.4
C99/C11 6.3.1.4
当实浮点类型的有限值转换为_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零).如果值整数部分不能用整数类型表示,行为未定义.
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
根据 C11 6.3.1.4 脚注 61:
According to C11 6.3.1.4 footnote 61:
将整数类型的值转换为无符号类型时执行的余数运算不需要在将实浮点类型的值转换为无符号类型时执行.因此,可移植实浮点值的范围是(-1,Utype_MAX+1).
The remaindering operation performed when a value of integer type is converted to unsigned type need not be performed when a value of real floating type is converted to unsigned type. Thus, the range of portable real floating values is (−1, Utype_MAX+1).
这篇关于将负双精度转换为无符号整数的行为是否在 C 标准中定义?ARM 与 x86 上的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!