c语言算一些数老是错误,C语言浮点运算感觉很奇怪同样的数,算出来结果却不一样,这是怎么回事?...

本文解释了计算机如何将十进制表达式转换为二进制进行存储和运算,探讨了二进制小数的权重计算,并指出浮点数存储(如float和double)存在的精度问题。重点讲解了转换过程中的误差来源,包括编码方式和运算局限。
摘要由CSDN通过智能技术生成

计算机存储和运算都是以二进制处理的,而表达式是十进制的,那么存储或运算时是要转换成二进制,计算完成后输出还要再转换成十进制。

那么你应该明白二进制每一位权重都是2^N,此处N为位号,位号分布如下:

...3,2,1,0(小数点) -1,-2,-3...

权重分布如下:

...2^3,2^2,2^1,2^0 (.小数点)2^-1,2^-2,2^-3

例如一个二进制的1.111(B)=1.875(D)

整数部分:1的位号为0,因此1*2^0=1*1=1

小数点向右第一个1:位号为-1,因此1*2^-1=1*1/2=0.5

小数点向右第二个1:位号为-2,因此1*2^-2=1*1/4=0.25

小数点向右第三个1:位号为-3,因此1*2^-3=1*1/4=0.125

合起来1+0.5+0.25+0.125=1.875,其他位依此类推。

无需想得太多,你可以明显看到,二进制小数表达的数都是不同级别减半后的累加。与十进制的某些小数没有一一对应,显然转换必然会发生误差。

另一方面,存储时CPU会对十进制小数会进行编码,float的尾数长度为23位,阶码8位,符号占1位,共32位。double是64位,无论如何精度都是有限的,因此也会存在误差,1.1*100时编译器会将表达式先转换二进制并运算运算,运算后再编码存储到变量中或临时变量中,而运算是由CPU直接处理的,因此你可以看到有个0.000002的误差数,而printf是个函数,对误差进行了修正。

PS:简单了解下浮点数的编码方式网页链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值