一段简略的C程序,对输出结果有点小疑惑

一段简单的C程序,对输出结果有点小疑惑。
计算sum1 = 1.0 + 1.0/2.0 + 1.0/3.0 +............
  sum2 = 1.0 - 1.0/2.0 - 1.0/3.0 +............
我随便输入了5;
得到sum1=2.283334
  sum2=0.783333
在调试的时候监视变量发现,在第一个for循环的时候,当加上第三项也就是加上1.0/3.0的时候,
为什么sum1的值为1.83333337 而不是1.83333333
求解。

代码如下:

#include<math.h>
int main(void)
{
  float a,sum1,sum2;
  int time;
  printf("Enter the number of times[Enter q to end]:\n");
  while(scanf("%d",&time)==1)
  {
  for(a=1.0, sum1=0.0; (int)a<=time; a++)
  sum1 += 1.0/a;
  printf("sum1 = %f\n",sum1);
  for(a=1.0, sum2=0.0; (int)a<=time; a++)
  sum2 += (1.0/a)*pow(-1,a+1);
  printf("sum2 = %f\n",sum2);
  printf("\nEnter the number of times[Enter q to end]:\n");
  }
  printf("\nEND!\n");
  return 0;
}



------解决方案--------------------
double用于表示有效数字的2进制位数是52位,换算成十进制为15~16位
十进制小数中在15~16位后面的那些位都是前面这15~16个有效位的附带结果,如果你手动计算过2进制转10进制就知道什么意思

二进制的0.1换成十进制就是0.5,二进制的0.11换成十进制就是0.75,二进制的0.101换成十进制就是0.625
假如限定二进制的有效位数只有一位,那么上述第一个和第三个都只能四舍五入为0.1,在这种情况下,你怎么判断这个数在十进制中是0.5还是0.6?不可能

这个问题的根本原因,在于你习惯在算数学题时所使用的“精确数字”是建立在十进制上的
换一个进制,它立刻改头换面变得不再精确
最简单的例子,10进制的0.67,是一个精确的小数,换算成2进制,就是0.10101011……一个无限循环小数
所以double型浮点数无法精确表示0.67这个10进制精确小数,它只能保证“我所表示的数和0.67这个精确值的差值小于0.0000000000000001”

------解决方案--------------------
C中浮点数的默认类型是double,表达式及标准函数求值的结果都应该是double类型的,但若你将结果存入float变量中、或简单的%f格式输出,值的有效位会被截断(尾数去掉一部分)。
所以运算中应该优先考虑用double类型(如同整数用int),仅在考虑存储效率和输出环节时用float类型。
教书上动不动用float实际是误导。

7#说的正确。二、十进制数转换中,位数关系是3倍多不到4倍(不是整数倍)吧,double(二进制)的有效数位是52,快速估算除以3是17,少一点15--16位十进制有效位。
float(二进制)的有效数是24位,除以3是8,少一点6-7位十进制有效位。