浮点数的舍入和误差问题

#include <iostream>
using namespace std;
void main()
{ 
	float a;
    double b;
    a=123456.789e4;
    b=123456.789e4;
    printf("%f\n",a);
    printf("%lf",b);
}

执行结果:

1234567936.000000
1234567890.000000

float 型的值出现了误差,而且误差很大,下面来分析

内存:
a的机器码:
0x4e932c06
0 10011101 00100110010110000000110
b的机器码:
0x41d26580b4800000
0 10000011101 0010011001011000000010110100100000…0

可以发现高亮部分的机器码是相同的
这里总结两点:
一:阶码最高位的1是统一为了抵御对于的偏置常数而设置的
二:float 的底数位不够表示而发生了一些舍入

可以观察到 float 底数位的最后两位 由 01 变成了 10 ,因为 01 后面本还有值
——这就是舍入规则

这已经是尽量减小误差了——如果不进行舍入的话,误差将会更大!

PS:查看汇编代码时,有了神奇的发现!!

在这里插入图片描述
float 和 double 的数据都是先存在 xmm0 这个80位的寄存器中的
也印证了之前的舍入规则——看其后是否还有数来判断舍入~
(值从右边的mov到左边的寄存器)

再来看个例子

#include <iostream>
using namespace std;
void main()
{ 
	float a=2147483647;
    printf("%f",a);
}

运行结果:

2147483648.000000

a的机器码:
0 10011110 0000…0

如果是double型
0 10000011101 1111 1111 1111 1111 1111 1111 1100 000…0

高亮部分位 float 型的最后一位——其后还有数值——要进位!
变成了
0 10011110 0000…0
—— 2147483648 即2^31

Ps:进位到了阶码!!!!——奥利给就完了!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值