zsy姐姐的NH-03:关于浮点数精度问题的一些研究
其实还没有完全解决这个问题,先写着,发现写不下去就删帖
c语言的作业越来越ex人啦~
本周又做了一道“这位更是重量级”的NH-03
这道题看上去人畜无害,交了一发WA后才发现其ex之处:浮点数的精度问题
请看其测试案例:
x=0.0000 |0.0000
y=0.0000 |0.0000
r=3043.2868 |99824.4353
x0=99778.0351 |24721.0328
y0=99824.4353 |96714.9855
ans=No |YES
(果然选修题的数据范围开的都离谱。。。)
本题直接用double储存会损失精度而WA,因此我们想探索一下浮点数的精度储存机制(我们是怎么死的)
浮点数在内存储存中分为三个部分:符号位,指数位,尾数位;
float(单精度浮点数):32bit,分配:1,8,23;
double(双精度浮点数):64bit,分配:1,11,52;
储存时先把浮点数转化为二进制的科学计数法,
(小数保存为二进制:把小数不断×2,取整数部分)
eg:20.59375(float)
(20.59375)10=(10100.10011)2
//然后把二进制移位变为科学计数法
(10100.10011)2=1.010010011*2^4 // 左移了4位
转换完成,下一步把它写成符号位+指数位+尾数位叭~
因为float指数位为8bit,可以表示-127~128
(为什么会有负数:如果只有小数部分,那么需要右移小数点. 比如右移3位才能放到第一个1的后面, 就是-3),
然鹅我们并不想要负数,于是我们可以每个数都加上127(double+1023)
所以指数位(阶码)为:127+4=131
最后存储为:0(符号位)100 1001 1(阶码)010 0100 11(尾数)00 0000 0000 0000(后面补零补满36位)=(41A4C000)16
所以我们发现:
二进制科学计数法第一位一定是1
而又因为计算机很懒,肯定会尽可能节省空间,所以储存浮点数尾数时不储存第一位
因此float的精度为23+1=(24)2=(16 777 216)10=1e7
double的精度为52+1=(53)2=(9.007199254741e+15)10 //十六位左右
到这里我们大概学会了浮点数储存和精度
但似乎还解决不了上面的问题
因为我现在还不会捏~
本文作者:misasteria
本文链接:https://www.cnblogs.com/misasteria/p/15992268.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步