C 在不损失精度的情况下将无符号转换为双精度转换为无符号

C 在不损失精度的情况下将无符号转换为双精度转换为无符号,c,floating-point,c99,ieee-754,floating-point-conversion,C,Floating Point,C99,Ieee 754,Floating Point Conversion,将整数值转换为浮点值并再次转换回与原始整数值相同吗 例如: unsigned x = 42; double y = x; unsigned z = y; 假设编译器没有优化浮点转换,x==z是否总是计算为true 我怀疑浮点转换中的任何表示错误都会导致值的增加。因此,当将浮点值转换回整数值时,该值将被截断,从而始终生成原始整数值 我的假设正确吗?假设IEEE 754双精度格式为double,表达式x==z将对x的所有值计算为1。例如,如果编译器提供32位无符号int,这意味着所有可能的x值 您

将整数值转换为浮点值并再次转换回与原始整数值相同吗

例如:

unsigned x = 42;
double y = x;
unsigned z = y;
假设编译器没有优化浮点转换,
x==z
是否总是计算为true

我怀疑浮点转换中的任何表示错误都会导致值的增加。因此,当将浮点值转换回整数值时,该值将被截断,从而始终生成原始整数值


我的假设正确吗?

假设IEEE 754双精度格式为
double
,表达式
x==z
将对
x
的所有值计算为
1
。例如,如果编译器提供32位
无符号int
,这意味着所有可能的
x

您已经编辑了问题,询问从整数到浮点的转换。在大多数C实现中,此转换根据FPU舍入模式进行舍入,默认情况下舍入为最接近的偶数。从float到integer的转换存在不对称性(正如您所指出的,从float到int的转换总是截断)

然而,从整数到浮点的转换中的任何错误都不意味着你得到的是一个没有分数的部分,而是你得到的是一个错误的整数。例如,整数253+1被转换为表示253的
double
。由于这个原因,即使从浮点到整数的转换总是向上舍入,从浮点到整数的转换也会截断


从整数到浮点的转换中的舍入误差可能大于一:整数
555555555
转换为
double
时,被舍入为
555555328
,其二进制表示形式恰好比前者更简单。一半的时候,舍入是向上的:例如,
55555555855
被舍入为
5555556352
如果
double
遵循IEEE-754(如标签所示),则任何高达253的整数都具有双精度浮点数的精确表示。因此,假设
int
是32位的,是的,您可以将
无符号的
转换为
双精度的
,而不会丢失精度。

让我们假设您的浮点双精度类型是64位IEEE754类型。(C标准没有坚持这一点,但这是您标记的内容)

它取决于
无符号整数的大小。如果是32位,那么是的,如果是64位,那么不一定。(截止位于第53位:253+1是最小的正数,不能在IEEE浮点
double
中精确表示)

在32位平台上,答案总是肯定的


在64位平台上,它取决于编译器。在LP64和LLP64中,
unsigned int
为32位,但在ILP64中为64位。(请注意,Win64使用LLP64,它还将
long
设置为32位)。

受C 2011(N1570)6.3.1.4 2支持:“当整数类型的值转换为实浮点类型时,如果转换的值可以在新类型中精确表示,则该值保持不变。”“当实浮点类型的有限值转换为除_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。”@chux:254-1有54位。例如,24-1是二进制1111。@chux:21-1是二进制1;它有1位。22-1是二进制11;它有2位。23-1是二进制111;它有3位。24-1是二进制1111;它有4位。25-1是二进制11111;它有5位…254-1有54位。在254-1中,从253位置到2**0位置的每个位置的位都是1。也就是说54位。@PascalCuoq当你提到FPU舍入模式时,我有点困惑;我认为这只适用于
nearbyint
函数。你是说有些实现不截断非整数浮点值,而是在初始化带有
float
int
时使用当前的FPU舍入模式吗variable?@VilhelmGray从float到int的转换总是截断:这是标准所说的,这就是故事的结尾。当值完全可表示时,从int到float的转换产生完全相同的值(参见Eric挖掘的标准引用),以及当要转换的整数值在目标类型中不可精确表示时,实现定义的上限值或下限值的选择。大多数C实现将该选择定义为:“根据FPU舍入模式当前设置的内容”。否,转换不会始终保持相同的值或增加值。如果源值完全可表示,则不会出现错误。如果源值不完全可表示,则将其舍入到最接近的可表示值(在通常的默认舍入模式下),其有效位的最小有效位(浮点格式的小数部分)为零。因此,舍入有时向上,有时向下。@EricPostChil因此,对于大于253的整数,可能是向下舍入值的情况,因此当转换回整数时,截断值小于原始值(即
x==z
对于大于253的整数,可能导致
0
)?是的,Pascal Cuoq在中给出了一个示例253+1。请注意,当值转换回整数时,它不会被截断,因为它仍然是整数。例如,将253+1转换为
double
会产生253。将其转换回64位整数格式会产生253。第二次转换是精确的;它不会截断或舍入,因为该值在新目标中完全可表示