文章目录
double相关的浮点编码学习
与float 类似
float double
存储长度 4byte 8byte
存储位数 32bit 64bit
符号位 1 1
指数位 8 11
有效位 23 52
double的指数位 是 加上1023 占11位 其余都与float计算一样
构造一个unsigned int类型的数字,将它赋值给float类型后,会丢失数据
100000000000000001
反汇编IDA
exe到obj到c文件
以下代码会出现崩溃
int main()
{
char chValue=0;
scanf("%d",&chValue);
printf("%d",chValue);
return 0;
}
原因所在,char类型所占一个字节
scanf中%d是整型类型 所占4个字节 所以就会占其他本不属于自己的空间 栈破坏掉了
printf
int main()
{
int nValue = 0xffffffff;
unsigned uValue = 0xffffffff;
printf("%d %d\r\n", nValue, uValue);
printf("%u %u\r\n", nValue, uValue);
}
以上调试过程中
当nValue 与uValue存进去的时候 数据都是一样的 存入的都是0xffff ffff
只有当printf输出的时候 才会改变
printf会减慢运行速度 相当于单片机的IO口
void Myfun(unsigned uCount)
{
for (size_t i = 0; i < uCount; i++)
{
printf("%d\r\n", i);
}
}
int main()
{
Myfun(-1);
}
以上的-1 会被强制转化为-1的16进制0xffffffff
就会很大 printf会处理
当时如果注释掉中间的printf
后面加上一个printf时间不会用的那么多
void Myfun(unsigned uCount)
{
for (size_t i = 0; i < uCount; i++)
{
//printf("%d\r\n", i);
}
printf(" Hello world!");
}
浮点编码
科学计数法
用科学计数法表示1234566.222 0.555666
1.234566222
∗
1
0
6
1.234566222*10^6
1.234566222∗106
5.55666
∗
1
0
−
1
5.55666*10^{-1}
5.55666∗10−1
十进制小数如何转换为二进制的小数
5.625对应的二进制为多少?
101.101
对于十进制的5.625,可以看作:
5
∗
1
0
1
+
6
∗
1
0
−
1
+
2
∗
1
0
−
2
+
5
∗
1
0
−
3
=
5.625
5*10^1+6*10^{-1}+2*10^{-2}+5*10^{-3}=5.625
5∗101+6∗10−1+2∗10−2+5∗10−3=5.625
101.101的二进制:
1
∗
2
2
+
1
∗
2
0
+
1
∗
2
−
1
+
1
∗
2
−
3
1*2^{2}+1*2^{0}+1*2^{-1}+1*2^{-3}
1∗22+1∗20+1∗2−1+1∗2−3
就是
1.01101
∗
2
2
1.01101*2^{2}
1.01101∗22
浮点编码方案及转化步骤
表达一个小数,从科学计数法,需要三个部分:
- 符号
- 有效数字
- 指数
以float为例 sizeof(float)=4,一共有32位,在float方案中,将32位划分以下三个部分: - 31bit:符号位 最高位,如果为1 表示为负数,否则表示为正数。
- 中间的8bit:指数部分,可以为正指数,也可以是负指数。
- 其余的23bit:有效数字部分,不足补0。
进一步的解释,对于一个已经转为科学计数法的二进制浮点数:
中间8bit表示指数,因为指数可以为正为负,所以编码规范中做了以下规定
将科学计数法中的指数部分,加上127后得到的结果,作为指数部分的数据。
有效数字位:二进制 只有0 1 但是科学计数法 必须为非零数值(所以必须为1),所以只需要记录小数部分
实例验证
转化为5.625,来得到计算机的16进制 验证
将上数字转化为二进制科学计数法
$ 1.01101*2^{2}$
符号位为 0
指数位为 2+127=129 1000 0001
有效数字位 01101
以上拼接起来就是 0 1000 0001 01101 000000000000000000
合起来 01000000101101000000000000000000
=>0100 0000 1011 0100 0000 0000 0000 0000
0x 40 B4 00 00
验证如下
面试题目
对于两个浮点型是否直接用==判断相等
答 不可以
int main()
{
float fValue1 = 3.14f;
float fValue2 = 3.0f;
fValue2 += 0.1f;
fValue2 += 0.04f;
if (fValue1 == fValue2)
{
printf("相等\r\n");
}
else
{
printf("不相等\r\n");
}
}
因为这关于3.14转为为机器16进制的时候 会出现无限取整数的情况 所以会产生小误差
解决方案如下
将两个数相减 然后差值小于一定范围就可
int main()
{
float fValue1 = 3.14f;
float fValue2 = 3.0f;
fValue2 += 0.1f;
fValue2 += 0.04f;
if (fValue1-fValue2<0.0001&&
fValue1-fValue2>-0.001)
{
printf("相等\r\n");
}
else
{
printf("不相等\r\n");
}
}