int x=25,i;
float *p=(float *)&x;
printf("%f\n",*p);
我理解浮点数和int的位表示是不同的,但无论我存储什么值,答案总是0.000000。取决于浮点表示,它不应该是其他值吗?
答案 0 :(得分:6)
您的代码具有未定义的行为 - 但只要类型int
和float
的大小和对齐方式兼容,它很可能会按预期运行。
使用“%f”格式打印*p
,您将丢失大量信息。
试试这个:
#include <stdio.h>
int main(void) {
int x = 25;
float *p = (float*)&x;
printf("%g\n", *p);
return 0;
}
在我的系统上(可能在你的系统上),它会打印:
3.50325e-44
int
值25
在其大多数高位中都为零。这些位可能与类型float
的指数字段位于同一位置 - 导致数字非常小。
查找IEEE浮点表示以获取更多信息。字节顺序将是一个问题。 (除非你有非常充分的理由,否则不要在实际代码中执行此类操作。)
正如rici在评论中所建议的,学习浮点表示的更好方法是从浮点值开始,将其转换为相同大小的无符号整数,并以十六进制显示整数值。例如:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void show(float f) {
unsigned int rep;
memcpy(&rep, &f, sizeof rep);
printf("%g --> 0x%08x\n", f, rep);
}
int main(void) {
if (sizeof (float) != sizeof (unsigned int)) {
fprintf(stderr, "Size mismatch\n");
exit(EXIT_FAILURE);
}
show(0.0);
show(1.0);
show(1.0/3.0);
show(-12.34e5);
return 0;
}
答案 1 :(得分:0)
出于本讨论的目的,我们假设int
和float
都是32位宽。我们还将承担IEEE-754浮标。
浮点值表示为sign * βexp * signficand
。对于32位二进制浮点数,β
为2
,指数 exp
的范围为-126
到127
,而< em> significand 是规范化二进制分数,因此在小数点之前存在单个前导非零位。例如,25
的二进制整数表示是
110012
而25.0
的二进制浮点表示形式为:
1.10012 * 24 // normalized
32位浮点数的IEEE-754编码
s eeeeeeee fffffffffffffffffffffff
其中s
表示符号位,e
表示指数位,f
表示有效位(分数)位。使用&#34;超过127&#34;编码指数。表示法,表示指数值127
(011111112
)表示0
,而1
(000000012
)表示-126
和{{1} }(254
)代表111111102
。未显式存储有效位数的前导位,因此127
将被编码为
25.0
但是,将32位整数值0 10000011 10010000000000000000000 // exponent 131-127 = 4
的位模式映射到32位浮点格式时会发生什么?我们结束了以下几点:
25
事实证明,在IEEE-754浮点数中,指数值0 00000000 00000000000000000011001
被保留用于表示000000002
和次正常(或非正规)数字。次正规数是接近0.0
的数字,不能表示为0
,因为指数必须小于我们可以用8位编码的数量。这些数字被解释为1.??? * 2exp
,并根据需要提供尽可能多的前导0.??? * 2-126
。
在这种情况下,它最多为0
,这为我们提供了0.000000000000000000110012 * 2-126
。
您必须映射大整数值(超过3.50325 * 10-44
)以查看除0之外的任何内容到一堆小数位。而且,就像基思所说,无论如何,这都是未定义的行为。