博客简介
本篇博客是计算机系统课程的讨论内容,用作学习记录,主要介绍的是:int ,float ,double 的相互转换问题 ,分析两段代码并对int,float,double的转换规则进行总结。
分析代码
代码1:
#include <stdio.h>
#define MaxValue 0x7fffffff
int main()
{
int i=MaxValue;
float f=i;
int j= (int)f;
printf("%d\n",(i==j));
return 0;
}
此时如果判断(i==j),将返回 false,试分析:
int 表示
- i=01111111 1111111 1111111 1111111
- gdb调试:
int—> float
- INTMAX=
2^31-1
=1.111 1111 1111 1111 1111 1111 1111 111 1.111 1111 1111 1111 1111 1111 1111 111 *2^30
- 规格化:
value=1.111 1111 1111 1111 1111 1111 1111 111 1111 1111 1111 1111 1111 1111 1111 111 *2^30
s=0
exp=127+30=157=1001 1101
frac=111 1111 1111 1111 1111 1111 1111 111 1.111 1111 1111 1111 1111 1111 1111 111
valu=01001 1101 1111111 1111 1111 1111 1111 1111 111 1.111 1111 1111 1111 1111 1111 1111 111
向偶数舍入:
0100111 00000000 00000000 0000000
最后float的结果如下:
float->int
我们知道上面float的值为1000000 0000000 0000000 0000000
一眼就能看出来这是int的下限:
- 由于int是有符号整型,所以1做为符号位
- 这个数据是一个特殊的数值,-2147483648
==判断
代码2:
#include <stdio.h>
int main()
{
double d1 = 0.6;
float f = (float)d1;
double d2 = f;
printf("%d\n",(d1==d2));
return 0;
}
此时如果判断(i==j),将返回 false,试分析:
double数据0.6规格化
- 1+11+52
value=0.6=1.00110011001100110011001100110011001100110011001101....*2^-1 循环
s=0
exp=1023-1=1111111110
frac=00110011001100110011001100110011001100110011001101....
value11=011111110 00011001 10011001 10011001 100110011001100110011001101....
double—>float
- 1+8+23
value=0.6=1.00110011001100110011001100110011001100110011001101....*2^-1
s=0
exp=127-1=01111110
frac=00110011 00110011 0011010
value11=1.00110011001100110011010
00111111 00011001 10011001 10011010
float——>double
value=1.00011001 10011001 10011010*2^-1
s=0
exp=1023-1=1022=01111111110
frac=00011001 10011001 10011010 00000000 0000000 00000000 0000
最后的结果是:
00111111 1110000 11001100 11001100 11010000 00000000 00000000 00000000
比较d1和d2
我们发现,二者高32位是相同的,但是后面出现了不等,是位截取时舍入造成的
总结
在相互转换为题中,我们需要考虑这些因素
- 转换时是否发生符号位的直接赋值?
- 转换时是否发生截取的舍入?
- int型组成:
1+31
- float组成:
1+8+23
- double组成:
1+11+52