在C标准中是否定义了将负双精度转换为无符号int的行为?ARM与x86上的不同行为

在C标准中是否定义了将负双精度转换为无符号int的行为?ARM与x86上的不同行为,c,casting,floating-point,type-conversion,undefined-behavior,C,Casting,Floating Point,Type Conversion,Undefined Behavior,我有在不同平台上运行的代码,它们似乎得到了不同的结果。我在寻找一个恰当的解释 我希望对unsigned进行强制转换,使float或double的效果与int1的效果相同 窗口: double dbl = -123.45; int d_cast = (unsigned int)dbl; // d_cast == -123 double dbl = -123.45; int d_cast = (unsigned int)dbl; // d_cast == 0 绞车(臂): double

我有在不同平台上运行的代码,它们似乎得到了不同的结果。我在寻找一个恰当的解释

我希望对
unsigned
进行强制转换,使
float
double
的效果与
int
1的效果相同

窗口:

double dbl = -123.45; 
int d_cast = (unsigned int)dbl; 
// d_cast == -123
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
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
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:编者注:将超出范围的
无符号
值转换为有符号类型,如
int
是实现定义的(不是未定义的)。C17§6.3.1.3-3

因此,对于
(unsigned)dbl
在某些特定实现中最终成为一个巨大的正值的情况,
d_cast
的赋值也没有被标准确定下来。(该执行路径包含UB,因此ISO C在理论上已经不存在了)。实际上,编译器在普通2的补码机器上执行我们期望的操作,并且保持位模式不变。

No
此转换未定义,因此不可移植

C99/C116.3.1.4

当实浮点类型的有限值转换为除_Bool以外的整数类型时, 舍弃小数部分(即,该值向零截断)。如果 整数部分不能用整数类型表示,行为未定义

根据C11 6.3.1.4脚注61:

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


我敢打赌这一定和endianness有关。@DanielA.White:为什么?为什么它会和endianness有关?代码中甚至没有任何指针。@Daniel:我怀疑……当你对一个无符号int强制转换一个负双精度时,你期望会发生什么?很有趣。我个人不希望从该操作中得到任何有意义的东西。是的,但是当实浮点类型的有限值转换为除_Bool之外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为是未定义的(根据C标准),整数部分可以用整数类型表示是,脚注50似乎是专门添加的,以防止您建议的解释。是的,谢谢,有时候,你需要在这本书开始阅读之前把头猛击几下。因此,出于好奇,如果他/她认为他/她可能有一个负的浮点,并想将其转换为一个无符号整数,你该怎么办?先将其转换为有符号整数,然后再转换为无符号整数是否安全?在这里采取什么正确的方法?谢谢。如果在超出范围的情况下,最终值不重要,那么只需进行赋值。如果最终的值很重要,那么在转换之前根据脚注50范围对其进行测试,并做一些让应用程序满意的事情(虽然它仍然是FP值)。