在C语言中,从int到float的转换是否总是可能的,而float不会变成像+Inf或-Inf这样的特殊值之一?AFAIK int的范围没有上限。我认为128位int会导致IEEE 754 float平台出现问题,因为其上限值约为2的127次幂。
int
float
fnx2tebb1#
简短回答您的问题:不,这并不总是可能的。但是,我们有必要更详细地了解一下,下面的段落显示了该标准对整数到浮点转换的说明(在线C11标准草案):
2)当一个整数类型的值被转换成一个真实的浮点类型时,如果被转换的值可以用新的类型精确地表示,则它不会改变。如果被转换的值在可以表示但不能精确地表示的值的范围内,则结果是最接近的较高或最接近的较低的可表示值。以实作定义的方式选择。如果要转换的值超出可表示的值范围,则行为未定义。...很多整数值可以被精确地转换。有些整数值可能会失去精度,但至少转换是可能的。然而,对于有些值,行为可能是未定义的(例如,如果一个整数值不能用浮点值的最大指数表示)。但实际上我不能假设这种情况会发生。
wz8daaqr2#
是否始终可以将int转换为float?合理-是的。int总是转换为有限的float。对于较大的int值,转换可能会丢失一些精度。然而,对于迂腐的人来说,一个奇怪的编译器可能会有麻烦。C语言允许int过宽,而不仅仅是16、32或64位,并且float可能有一个限制范围,小到1 e37。值得关注的不是int或INT_MAX的 * 上限 *,而是INT_MIN的 * 下限 *,它的星等通常比INT_MAX大+1。124位int最小值可能约为-1.06e37,因此这确实超出了最小float范围。对于常见的binary32float,int需要超过128位才能导致float无穷大。那么,需要什么样的测试来检测这种罕见的情况呢?形成一个精确的2的幂的限制,并执行仔细的数学运算,以避免溢出或不精确。
INT_MAX
INT_MIN
#if -INT_MAX == INT_MIN // rare non 2's complement machine #define INT_MAX_P1_HALF (INT_MAX/2 + 1) _Static_assert(FLT_MAX/2 >= INT_MAX_P1_HALF, "non-2's comp.`int` range exceeds `float`"); #else _Static_assert(-FLT_MAX <= INT_MIN, "2's complement `int` range exceeds `float`"); #endif
lymgl2op3#
该标准只要求浮点数表示包含一个最大为1037的有限数(§5.2.4.2.2/12),并且对整数的最大长度没有任何限制。因此,如果您的实现包含128位整数(甚至124位整数),整数到浮点数的转换可能会超出有限可表示浮点数的范围。
qcbq4gxm4#
不能,由于浮点的工作方式,并不总是可以将int转换为float。32位浮点大于16777216(或小于-16777216)需为偶数,大于33554432(或小于-33554432)需要能被4整除,大于67108864 IEEE-754浮点标准将舍入到最接近的偶数定义为默认模式,但是根据实现方式存在其它模式。还有,最大的128位整型数= 2^128 - 1大于最大的32位浮点数= 2^127 x 1.1111111111111111111111 = 2^127 x(2-2^-23)= 2127 x(21 -2^-23)= 2^(127+1)- 2^(127-23)= 2^(127+1)-2 ^(127 -23)= 2^(128)- 2^(104)
4条答案
按热度按时间fnx2tebb1#
简短回答您的问题:不,这并不总是可能的。
但是,我们有必要更详细地了解一下,下面的段落显示了该标准对整数到浮点转换的说明(在线C11标准草案):
6.3.1.4真实的浮点和整数
2)当一个整数类型的值被转换成一个真实的浮点类型时,如果被转换的值可以用新的类型精确地表示,则它不会改变。如果被转换的值在可以表示但不能精确地表示的值的范围内,则结果是最接近的较高或最接近的较低的可表示值。以实作定义的方式选择。如果要转换的值超出可表示的值范围,则行为未定义。...
很多整数值可以被精确地转换。有些整数值可能会失去精度,但至少转换是可能的。然而,对于有些值,行为可能是未定义的(例如,如果一个整数值不能用浮点值的最大指数表示)。但实际上我不能假设这种情况会发生。
wz8daaqr2#
是否始终可以将
int
转换为float
?合理-是的。
int
总是转换为有限的float
。对于较大的int
值,转换可能会丢失一些精度。然而,对于迂腐的人来说,一个奇怪的编译器可能会有麻烦。
C语言允许
int
过宽,而不仅仅是16、32或64位,并且float
可能有一个限制范围,小到1 e37。值得关注的不是
int
或INT_MAX
的 * 上限 *,而是INT_MIN
的 * 下限 *,它的星等通常比INT_MAX
大+1。124位
int
最小值可能约为-1.06e37,因此这确实超出了最小float
范围。对于常见的binary32
float
,int
需要超过128位才能导致float
无穷大。那么,需要什么样的测试来检测这种罕见的情况呢?
形成一个精确的2的幂的限制,并执行仔细的数学运算,以避免溢出或不精确。
lymgl2op3#
该标准只要求浮点数表示包含一个最大为1037的有限数(§5.2.4.2.2/12),并且对整数的最大长度没有任何限制。因此,如果您的实现包含128位整数(甚至124位整数),整数到浮点数的转换可能会超出有限可表示浮点数的范围。
qcbq4gxm4#
不能,由于浮点的工作方式,并不总是可以将
int
转换为float
。32位浮点大于16777216(或小于-16777216)需为偶数,大于33554432(或小于-33554432)需要能被4整除,大于67108864 IEEE-754浮点标准将舍入到最接近的偶数定义为默认模式,但是根据实现方式存在其它模式。还有,最大的128位整型数= 2^128 - 1大于最大的32位浮点数= 2^127 x 1.1111111111111111111111 = 2^127 x(2-2^-23)= 2127 x(21 -2^-23)= 2^(127+1)- 2^(127-23)= 2^(127+1)-2 ^(127 -23)= 2^(128)- 2^(104)