本文介绍了将负双精度转换为无符号整数的行为是否在 C 标准中定义?ARM 与 x86 上的不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有在不同平台上运行的代码,似乎得到不同的结果.我正在寻找适当的解释.

I have code that runs on different platforms that seems to get different results. I am looking for a proper explanation.

我希望 unsigned 的转换对 floatdoubleint.

I expected casting to unsigned to work the same for float or double as for int.

解决方法

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以外的整数类型时,小数部分被丢弃(即,该值被截断为零).如果值整数部分不能用整数类型表示,行为未定义.

根据 C11 6.3.1.4 脚注 61:

According to C11 6.3.1.4 footnote 61:

将整数类型的值转换为无符号类型时执行的余数运算不需要在将实浮点类型的值转换为无符号类型时执行.因此,可移植实浮点值的范围是(-1,Utype_MAX+1).

这篇关于将负双精度转换为无符号整数的行为是否在 C 标准中定义?ARM 与 x86 上的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 19:46