为什么从 int 转换为 float 值?
Why does a cast from int to float round the value?
我正在阅读 CS:APP,关于转换,它说当将 从 int 转换为 float 时,数字不能溢出,但它可能会被四舍五入。
这对我来说似乎很奇怪,因为我不知道要舍入什么,所以我已经试过了。我认为只有非常大的整数(接近 INT_MAX
/INT_MIN
)才会出现这种情况,但四舍五入也发生在大约一亿的值上。 (不确定首先发生这种情况的确切位置)。
为什么会这样? float
的范围远远超过int
的范围。有人可能会说浮点数不能精确表示,但是从 int
转换为 double
时,值没有变化。 double
优于 float
的优点是它具有更大的范围和精度。但是 float
仍然有足够的范围到 "encapsulate" 整数,精度不应该真正重要,因为整数没有小数位(好吧,全是 0),或者我想错了?
这是我得到的一些输出(这里是代码:http://pastebin.com/K3E3A6Ni):
FLT_MAX = 340282346638528859811704183484516925440.000000
INT_MAX = 2147483647
(float)INT_MAX = 2147483648.000000
(double)INT_MAX = 2147483647.000000
INT_MIN = -2147483648
(float)INT_MIN = -2147483648.000000
====other values close to INT_MIN INT_MAX====
INT_MAX-1 = 2147483646
(float)INT_MAX-1 = 2147483648.000000
INT_MIN+1 = -2147483647
(float)INT_MIN+1 = -2147483648.000000
INT_MAX-2 = 2147483645
(float)INT_MAX-2 = 2147483648.000000
INT_MAX-10 = 2147483637
(float)INT_MAX-10 = 2147483648.000000
INT_MAX-100 = 2147483547
(float)INT_MAX-100 = 2147483520.000000
INT_MAX-1000 = 2147482647
(float)INT_MAX-1000 = 2147482624.000000
(float)1.234.567.809 = 1234567808.000000
(float)1.234.567.800 = 1234567808.000000
(float)1.000.000.005 = 1000000000.000000
(float)800.000.003 = 800000000.000000
(float)500.000.007 = 500000000.000000
(float)100.000.009 = 100000008.000000
使用 32 位 IEEE-754 表示实现的典型 float
只有 24 位有效数字,允许大约 7 位十进制数字的精度。因此,一旦达到数百万 (224 约 16M),您就会看到四舍五入。
(对于double
,有效数有53位,253 约9×1015。 )
我假设 float
是指 32 位 IEEE-754 二进制浮点值,double
是指 64 位 IEEE-754 二进制浮点值, int
是指 32 位整数。
Why does this happen? The range of float far exceeds that of int
是的,但是float
的精度只有7-9位小数。更具体地说,有效数字只有 24 位宽...所以如果你试图在其中存储 32 位信息,你就会遇到问题。
but when converting from int
to double
there is no change in value
当然可以,因为 double
有一个 53 位有效数字 - 那里有足够的空间容纳 32 位整数!
换句话说,连续 int
值之间的差距始终为 1...而连续 float
值之间的差距开始非常非常小...但随着值的大小增加。它在您达到 int
的限制之前就达到了 "more than 2"... 所以您进入了并非每个 int
都可以准确表示的阶段。
想起来另一种方式,你可以简单地使用pigeon-hole principle...甚至忽略NaN值,最多可以有 232 float
个值,其中至少有一个不是 int
的精确值 - 例如,取 0.5。有 232 int
个值,因此至少有一个 int
值没有精确的 float
表示。
我正在阅读 CS:APP,关于转换,它说当将 从 int 转换为 float 时,数字不能溢出,但它可能会被四舍五入。
这对我来说似乎很奇怪,因为我不知道要舍入什么,所以我已经试过了。我认为只有非常大的整数(接近 INT_MAX
/INT_MIN
)才会出现这种情况,但四舍五入也发生在大约一亿的值上。 (不确定首先发生这种情况的确切位置)。
为什么会这样? float
的范围远远超过int
的范围。有人可能会说浮点数不能精确表示,但是从 int
转换为 double
时,值没有变化。 double
优于 float
的优点是它具有更大的范围和精度。但是 float
仍然有足够的范围到 "encapsulate" 整数,精度不应该真正重要,因为整数没有小数位(好吧,全是 0),或者我想错了?
这是我得到的一些输出(这里是代码:http://pastebin.com/K3E3A6Ni):
FLT_MAX = 340282346638528859811704183484516925440.000000
INT_MAX = 2147483647
(float)INT_MAX = 2147483648.000000
(double)INT_MAX = 2147483647.000000
INT_MIN = -2147483648
(float)INT_MIN = -2147483648.000000
====other values close to INT_MIN INT_MAX====
INT_MAX-1 = 2147483646
(float)INT_MAX-1 = 2147483648.000000
INT_MIN+1 = -2147483647
(float)INT_MIN+1 = -2147483648.000000
INT_MAX-2 = 2147483645
(float)INT_MAX-2 = 2147483648.000000
INT_MAX-10 = 2147483637
(float)INT_MAX-10 = 2147483648.000000
INT_MAX-100 = 2147483547
(float)INT_MAX-100 = 2147483520.000000
INT_MAX-1000 = 2147482647
(float)INT_MAX-1000 = 2147482624.000000
(float)1.234.567.809 = 1234567808.000000
(float)1.234.567.800 = 1234567808.000000
(float)1.000.000.005 = 1000000000.000000
(float)800.000.003 = 800000000.000000
(float)500.000.007 = 500000000.000000
(float)100.000.009 = 100000008.000000
使用 32 位 IEEE-754 表示实现的典型 float
只有 24 位有效数字,允许大约 7 位十进制数字的精度。因此,一旦达到数百万 (224 约 16M),您就会看到四舍五入。
(对于double
,有效数有53位,253 约9×1015。 )
我假设 float
是指 32 位 IEEE-754 二进制浮点值,double
是指 64 位 IEEE-754 二进制浮点值, int
是指 32 位整数。
Why does this happen? The range of float far exceeds that of int
是的,但是float
的精度只有7-9位小数。更具体地说,有效数字只有 24 位宽...所以如果你试图在其中存储 32 位信息,你就会遇到问题。
but when converting from
int
todouble
there is no change in value
当然可以,因为 double
有一个 53 位有效数字 - 那里有足够的空间容纳 32 位整数!
换句话说,连续 int
值之间的差距始终为 1...而连续 float
值之间的差距开始非常非常小...但随着值的大小增加。它在您达到 int
的限制之前就达到了 "more than 2"... 所以您进入了并非每个 int
都可以准确表示的阶段。
想起来另一种方式,你可以简单地使用pigeon-hole principle...甚至忽略NaN值,最多可以有 232 float
个值,其中至少有一个不是 int
的精确值 - 例如,取 0.5。有 232 int
个值,因此至少有一个 int
值没有精确的 float
表示。