刚才见有人列举vc6令人发指的罪行,其罪行是否到了令人发指的地步就不说了,倒是让我想起了曾经碰到的怪问题,不知是我程序的问题还是编译器的问题,在vc和tc下运行总是怪怪的,代码如下:// TestFloat.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include "stdio.h"/*
 * 测试float数据的运算精度
 *
 * !!!发现使用指针会使精度下降!!!
 */int main(int argc, char* argv[])
{
float f=752;
float *pf=&f;
*pf += 0.000001;
printf("*pf + 0.000001 = (*pf)%.15f\n", *pf);
printf("*pf + 0.000001 = %.15f\n", f);
f += 0.000001;
//printf("f + 0.000001 = (*pf)%.15f", *pf); //取消屏蔽此句会使下一句输出为0
printf("f + 0.000001 = %.15f\n", f);
printf("f + 0.000001 = (*pf)%.15f\n", *pf);
return 0;
}其在vc下输出为:
  *pf + 0.000001 = (*pf)752.000000000000000
  *pf + 0.000001 = 752.000000000000000
  f + 0.000001 = 752.000001000000000
  f + 0.000001 = (*pf)752.000000000000000注意其中使用指针与不使用指针时的区别,另外各位可以在其它环境中试一下,不知在其它编译器中如何?呵呵,这个问题应该怪谁呢?

解决方案 »

  1.   

    这个还不算离谱,有人能把0=1吗?vc6竟然可以做到*(int *)0=1;呵呵,指针真是神奇呀,竟然连几千年的东西给推翻了。
      

  2.   

    *(int *)0=1;
    这个语句是不是把1赋给地址为0的那个空间啊?
      

  3.   

    *(int *)0=1;
    --指针最绕人了...
      

  4.   

    VC还是比较稳定地~~~~
    指针的确是绕来绕去
    消耗程序员的脑细胞和时间
    换来CPU节约出来的那么一点点时间!
      

  5.   

    使用double,float对小数的支持不够,好像有6位有效数字吧.
    0.000001 在默认状态下就是double类型的,会先强制转换成float再与float型的*pf相加,应该有个警告才对,实在要用float的话,使用0.000001f.
      

  6.   

    188:      *pf += 0.000001f;
    004023C0   mov         ecx,dword ptr [ebp-0Ch]
    004023C3   fld         dword ptr [ecx]
    004023C5   fadd        dword ptr [__real@4@3feb8637bd0000000000 (0041501c)]
    004023CB   mov         edx,dword ptr [ebp-0Ch]
    004023CE   fstp        dword ptr [edx]191:      f += 0.000001f;
    00402420   fld         dword ptr [ebp-8]
    00402423   fadd        dword ptr [__real@4@3feb8637bd0000000000 (0041501c)]
    00402429   fst         dword ptr [ebp-8]生成的汇编码中,计算结果的代码都是一样的,而且是按double来算的,有效位要大得多,但指针操作时多用了回送结果的指令fstp,因此结果中的多余的有效数位就在传输过程中损失了.直接用fst时操作时,double计算中产生的多余有效位依然在f变量所在空间,所以看上去似乎没有损失.
      

  7.   

    *(int *)0=1;//这个有何不对??完全合法啊.只是在windows的内存模型下你不能这么做罢了.
      

  8.   

    *(int *)0=1;这行等价于:
    void*  pVal = NULL;
    int*   pIntVal= (int*) pVal;
    *pIntVal = 1;编译器当然认为合法,只是会发生运行时错误。
      

  9.   

    ok,c/c++暴露了那么多的底层细节,就是假设程序员有能力避免这些带来的弊端。
    如果你不行,就不要做这个了。什么叫做几千年的东西被推翻,回去好好学学谭浩强
    的书你就不会这么想。指针时什么都压根不知道,就来批驳。这样可不好。