CString str;
float f1,f2,f3,f4,tf1,tf2;
f1 = 4E13;
f2 = 3.0;
f3 = 7E6;
f4 = 5.9E6;
tf1 = f1*(f3-f4)/(f2*f3*f4);
tf2 = f1*(f3-f4)/(f2*f3*f4);
     
str.Format("Period : %f,%f,%f\r\n",tf1,tf2,tf2-tf1);
AfxMessageBox(str);以上这段代码输出的结果:
         Test result: tf1=355125.093750,tf2=355125.093750,tf2-tf1=0.001029
         为什么会出现 tf2-tf1 非零?
如果将 float改为 double,tf2-tf1=0.000000
         另,如果在 str.Format前面任意 进行一次 float类型数据的运算,也能使得 tf2-tf1=0.00000.  这又是怎么一回事?
         请高人指点
         
编译环境:VC6,sp5 + XP,sp1

解决方案 »

  1.   

    编译器问题?下面是VC7.0里的输出
    Period : 355125.093750,355125.093750,0.000000
      

  2.   

    哎,从你的问题可以看出你不知道浮点型数据计算机是怎么记录的,只有有小数点的,严格上来讲他就不可能完全准备,它只能是相对准备,知不知道怎么判断一个浮点型数据是否等于或不等于吗?
    float f1;
    if(f1 == 0) if(f1 != 0)?
    这样做嘛?错,这样做是不准确的,浮点型一定是相对,记住,应该如下:
    #define HHH 0.00001  //我要要精确到0.00001
    if(((f1 - HHH) > 0) || ((f1 - HHH) < 0))  //这才是不等0的判断
    等于0的就不说了。
    不知道你明白不明白我的意思了。用浮点型要用好是别那么草率的,否则有些值是骗你的。
      

  3.   

    恩~~~
    是编译器问题了~~
    我用VC6.0编译结果和楼主相同~~
    用VC7.0结果同楼上相同~~~
      

  4.   

    会不会是这样,执行运算的时候楼主的编译器将float的运算结果存到内存,这时会丢失精度,但如果在tf2运算后马上printf,编译器判断接下来还会用到tf2,因此没有将其存入内存,因此tf1经过浮点寄存器->内存->浮点内存器而丢失了精度,当然这种行为是因编译器甚至因操作系统而异的,所以有的编译器不会出这问题
      

  5.   

    double因为存储精度高了所以就没有丢失(double在内存中是64位的)
      

  6.   

    恩~
    本身double精度就比较高~~
      

  7.   

    因为float本身在机器内部表示不精确的。有一点小误差是正常的
      

  8.   

    经过大家的指点,倾向于编译器优化问题。
    勾选 Project Settings-->C/C++ -->Optimizations-->Customize-->Inprove Flat Consistency (或直接在 Options 里添加开关 /Op )
    即避免了该问题,谢谢!Microsoft Visual C++ 浮点优化:
    http://www.microsoft.com/china/MSDN/library/langtool/VCPP/USdv_vstechartfloapoint.mspx?mfr=true