Nev*_*own -3 c c++ floating-point int format-specifiers
这是我的代码,我不知道为什么会发生这种情况:
#include <stdio.h>
void foo(float *);
int main()
{
int i = 10, *p = &i;
foo(&i);
}
void foo(float *p)
{
printf("%f\n", *p);
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
Run Code Online (Sandbox Code Playgroud)
正如已经说过的那样,您将整数变量的地址作为单精度浮点数的地址传递.
理想情况下,应该禁止这种隐式转换,但是根据编译器以及它是干净的C还是C++,它可能只会导致警告.
但为什么它打印正好0?
这是因为单精度FPN 在内存中的表示方式:
(1 bit of sign)|(8 bits of biased exponent)|(23 bits of significand(mantissa))
Run Code Online (Sandbox Code Playgroud)
二进制10是
0|0000 0000|000 0000 0000 0000 0000 0000 1010
Run Code Online (Sandbox Code Playgroud)
因此,当解释为浮点值时:
(sign = 0)(biased exponent = 0)(significand = 10)
Run Code Online (Sandbox Code Playgroud)
偏差指数是正常指数加上127 - http://en.wikipedia.org/wiki/Exponent_bias
要计算值,我们将使用以下公式:
floatValue = ((sign) ? (-1) : (1)) * pow(2, normalExponent) * significand
Run Code Online (Sandbox Code Playgroud)
这将产生:
floatValue = 1 * pow (2, 0 - 127) * 10 = 10 * 2 in pow -127.
Run Code Online (Sandbox Code Playgroud)
它是一个非常小的数字,当使用%f说明符表示变成"0"字符串时.
解:
要解决这个问题,只需使用临时变量和显式强制转换,然后再调用foo:
int main()
{
int i = 10;
float temp = (float)i;
foo(&temp);
}
void foo(float *p)
{
printf("%f\n", *p);
}
Run Code Online (Sandbox Code Playgroud)
PS为了避免将来出现此类问题,请始终将编译器设置为最大的实际警告级别,并在运行应用程序之前始终处理每个警告.
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |