是否总是可以将`int`转换为`float`
Posted
技术标签:
【中文标题】是否总是可以将`int`转换为`float`【英文标题】:Is it always possible to convert an `int` to a `float` 【发布时间】:2017-12-04 10:26:25 【问题描述】:在 C 中从 int
到 float
的转换是否总是可能的,而 float
不会成为 +Inf 或 -Inf 等特殊值之一?
AFAIK int
的范围没有上限。
我认为 128 位 int
会导致具有 IEEE754 float
的平台出现问题,因为它的上限值约为 2 的 127 次方。
【问题讨论】:
int 确实有一个最大值:***.com/questions/94591/… @chris int 不保证是 32 位,正好等于或大于 16 位。 @WillyWonka 无论您处理何种数据类型,都会有限制(因为这是真实世界,而不是无限的图灵机)。 对不起,我太高了。我认为 128 位int
就足够了。已编辑问题。我是新来的,有什么办法可以阻止投票吗?
@Chris 当然 int 会有一些上限。但是 OP 询问 int 的限制何时高于 float 的限制,例如具有 128 位 int 和 IEEE-754 单精度浮点数的平台
【参考方案1】:
简短回答您的问题:不,这并不总是可能的。
但值得深入了解一些细节。以下段落显示了标准对整数到浮点转换 (online C11 standard draft) 的说明:
6.3.1.4 实数浮点数和整数
2) 当整数类型的值转换为真正的浮点类型时, 如果被转换的值可以在新的 类型,它是不变的。如果要转换的值在 可以表示但不能准确表示的值 结果是可表示的最接近的更高或最接近的更低 值,以实现定义的方式选择。如果值是 转换后的值超出了可以表示的范围,则 行为未定义。 ...
这么多整数值可以精确转换。一些整数值可能会丢失精度,但至少可以进行转换。但是,对于某些值,行为可能是未定义的(例如,如果整数值无法用浮点值的最大指数表示)。但实际上我不能假设会发生这种情况。
【讨论】:
【参考方案2】:该标准仅要求浮点表示形式包含最大为 1037 (§5.2.4.2.2/12) 的有限数,并且对整数的最大大小没有任何限制。因此,如果您的实现具有 128 位整数(甚至 124 位整数),则整数到浮点数的转换可能会超出有限可表示浮点数的范围。
【讨论】:
【参考方案3】:是否总是可以将
int
转换为float
?
合理 - 是的。 int
将始终转换为有限的float
。对于较大的int
值,转换可能会丢失一些精度。
然而对于书呆子来说,一个奇怪的编译器可能会遇到麻烦。
C 允许int
过宽,而不仅仅是 16、32 或 64 位,float
可以有一个限制范围,小到 1e37。
应该关注的不是int
或INT_MAX
的上限 范围。它是下端。 INT_MIN
的幅度通常比 INT_MAX
大 +1。
124 位 int
最小值可能约为 -1.06e37,因此确实超出了最小 float
范围。
对于常见的binary32float
,int
伤口需要超过 128 位才能导致float
无穷大。
那么需要什么测试来检测这种罕见的情况呢?
形成一个精确的 2 次幂限制并执行仔细的数学运算以避免溢出或不精确。
#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
【讨论】:
以上是关于是否总是可以将`int`转换为`float`的主要内容,如果未能解决你的问题,请参考以下文章
无法将float类型隐式转换为int。存在显式转换(您是否缺少演员表?)
是否有更直接的方法将float转换为int而不是添加0.5f并使用截断转换?