2 wuifa WUIFA 于 2014.08.08 12:07 提问

程序编译无问题,运行结果却因数据不同出现差错,新人求解!!!

#include
#include
struct employee
{
char name[20];
int age;
char sex;
float salary;
};
void main()
{
struct employee *p;
p = (struct employee *)malloc(sizeof(struct employee));
gets(p->name);
p->age = 26;
p->sex = 'M';
p->salary = 1087.2;
printf("Namw=%s\nAge=%d\n",p->name,p->age);
printf("Sex=%c\nScore=%f\n",p->sex,p->salary);
free(p);
}
上面程序为何在vc6.0中运行,salary的结果1087.2,1087.4等不能正确显示,如果是1087.5却可以,求大神指点!

2个回答

liyun123gx
liyun123gx   2014.08.08 16:57

float类型有一个精确度的问题,比如1087.2不一定存储的就正好是这个数,可能是1087.199951.
我在自己这试了一下,不改输出的精度的话,就是1087.199951,但是精确到小数点后1位,就是1087.2了

WUIFA
WUIFA 谢谢了,不过为什么会有存储的数不是对应这个数的情况,不是赋值的时候确定了吗,而且赋的值还是确定的精度。
大约 3 年之前 回复
liyun123gx
liyun123gx   2014.08.11 10:56

float型存储,一位符号位,30位到23位是指数位(127+实际的指数),低23位是基数位。
以5.1为例: 5 = 0101B
0.1 =0.0 0011 0011 0011 0011 0011 0011 0011 0011 0011B……(不断循环)
故: 5.1 = 101.0 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011……
科学计数法表示:1.010 0011 0011 0011 0011 0011 0011 0011……*2^2
符号位:0 指数位:127+2 = 129( 1000 0001B)
基数位那就要只取0.1的二进制表示的前23位了: 0100 0110 0110 0110 0110 011 。
这样所存储的结果,和你赋值的数就会不同。
那对于1087.5来说,小数部分0.5,二进制表示是0.1,1087.5用2进制表示为:100 0011 1111.1,
也就是1.00 0011 1111 1 * 2^10,符号位为0,指数位:127+10,基数位是 0000 1111 1110 0000 000,那么1087.5在计算机中存储的值就是1087.5

Csdn user default icon
上传中...
上传图片
插入图片