计算机存储和运算都是以二进制处理的,而表达式是十进制的,那么存储或运算时是要转换成二进制,计算完成后输出还要再转换成十进制。
那么你应该明白二进制每一位权重都是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:简单了解下浮点数的编码方式网页链接