使用此代码:
#include <float.h>
printf("FLT_MAX = %en", FLT_MAX);
unsigned long ul = 1234567891011;
float f = (float)ul;
printf("f=%f", f);
我希望f=1234567891011.000000,这是我的带小数的整数。相反,结果是:
FLT_MAX = 3.402823e+38
f=1234567954432.000000
知道:
sizeof(long unsigned) = 8 bytes
sizeof(double) = 8 bytes
sizeof(float) = 4 bytes
我可以通过使用double而不是float来解决问题,但我想了解:
- 尽管1234567891011比ULONG_MAX(2^64(和FLT_MAX小得多,但为什么此铸造失败?(但实际上,比2^32大得多(
- FLT_MAX如何在仅有4个字节的情况下达到3.402823e+38
- 除了检查我的无符号长是否大于特定阈值之外,有没有一种干净的方法来处理这种情况?(2^32?(
PS:是的,有一个类似的老问题,但对于大数字来说是不正确的
尽管1234567891011比ULONG_MAX(2^64(和FLT_MAX小得多,但为什么此强制转换失败?(但实际上,可疑地大于2^32(
在您的C实现中,float
将有限数表示为一个符号、一个24位无符号整数和一个从104到−149的二次幂缩放。(这也被描述为一个24位二进制数字,其基点固定在第一位之后,2的幂在127到−126之间。这些在数学上是等价的。(
1234567891011不能用24位整数表示,也不能用2的幂进行缩放。上述float
格式中可表示的最接近值为4709503•218,等于1234567954432。因此,当1234567891011转换为float
时,结果为1234567954432。
FLT_MAX如何在只有4个字节的情况下达到3.402823e+38?
仅使用这12个字符如何达到3.402823e+38?只使用指数中的两位数字,2的幂如何达到299?我们如何用"无穷大"一词中的有限多个字母来表示无穷大的概念?
一个对象中的位数只会限制它可以代表多少不同的东西。它并不以任何方式控制它们所代表的内容。我们可以取三位,000表示零,001表示五,010表示−1,011表示π,100表示i(−1的平方根(,101表示苹果,110表示火星,111表示ennui。
在float
格式中,我们说第一个位代表符号(0代表+,1代表−(,接下来的八个位代表一个代码,主要代表2的指数,最后的23个位代表float
表示的大部分小数部分。指数代码使用1到254表示−126到+127之间的指数,也表示小数部分以"1"开头。指数代码0表示指数为−126,小数部分以"0"开头。指数码255表示表示的值是无穷大或特殊的"非数字"值,具体取决于最后23位。
由于指数代码位可以表示高达127的指数,因此float
对象可以表示分数部分的高达2127倍,分数部分可以高达略小于2(可以是2−2−23(。
除了检查我的无符号长是否大于特定阈值之外,还有一种干净的方法来处理这种情况吗?(2^32?(
它处理得很干净;float f = (float) ul;
尽可能好地转换了这个数字。如果你想要不同的处理方式,你需要描述你想要的不同结果。