将负双精度转换为无符号整数的行为是不是在 C 标准中定义? ARM 与 x86 上的不同行为
Posted
技术标签:
【中文标题】将负双精度转换为无符号整数的行为是不是在 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将负双精度转换为无符号整数的行为是否在 C 标准中定义? ARM 与 x86 上的不同行为 【发布时间】:2012-05-19 10:48:48 【问题描述】:我有在不同平台上运行的代码,似乎得到不同的结果。我正在寻找适当的解释。
我希望投射到unsigned
与float
或double
的工作方式与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
编辑:
感谢您指出正确的方向。
修复解决方法
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.
因此,对于 (unsigned)dbl
最终在某些特定实现上具有巨大正值的情况,标准也没有确定对 d_cast
的分配。 (该执行路径包含 UB,因此理论上 ISO C 已经不存在了)。实际上,编译器在正常的 2 的补码机器上执行我们所期望的操作,并保持位模式不变。
【问题讨论】:
我敢打赌这与字节序有关。 @DanielA.White:为什么哦,为什么它与字节序有任何关系?代码中甚至没有任何指针。 @Daniel:我怀疑... 当您将负双精度转换为无符号整数时,您期望会发生什么? 有趣。我个人不希望该操作有任何意义。 【参考方案1】:没有
此转换未定义,因此不可移植。
C99/C11 6.3.1.4
当实浮点类型的有限值转换为_Bool以外的整数类型时, 小数部分被丢弃(即,该值被截断为零)。如果值 整数部分不能用整数类型表示,行为未定义。
根据 C11 6.3.1.4 脚注 61:
将整数类型的值转换为无符号类型时执行的求余运算不需要在将实浮点类型的值转换为无符号类型时执行。因此,可移植实浮点值的范围是(-1,Utype_MAX+1)。
【讨论】:
是的,但是当实浮点类型的有限值转换为 _Bool 以外的整数类型时,小数部分被丢弃(即,该值被截断为 0)。如果整数部分的值不能用整数类型表示,则行为未定义(FROM THE C STANDARD)整数部分可以用整数类型表示 是的,并且似乎专门添加了脚注 50,以防止您建议的解释。 是的,谢谢,有时您需要在书本上猛击几下,然后它才会沉入其中。 那么,出于好奇,如果他/她认为他/她可能有一个负浮点数并想将其转换为无符号整数,该怎么办?是否先将其转换为有符号整数,然后再转换为无符号整数?在这里采取什么正确的方法?谢谢。 如果最终值对于超出范围的情况不重要,则只需执行分配即可。如果最终值很重要,那么在转换之前根据脚注 50 范围对其进行测试,并做一些让应用程序满意的事情(虽然它仍然是 FP 值)。以上是关于将负双精度转换为无符号整数的行为是不是在 C 标准中定义? ARM 与 x86 上的不同行为的主要内容,如果未能解决你的问题,请参考以下文章
DecimalFormat 为负双精度输入返回“?”而不是“-”
在C#中是否可以在没有类型转换的情况下将整数转换为无符号整数? [关闭]