不搞数值计算的人可能不会注意这个问题。
在大部分情况下很多人不会用到小数点后16位,但是程序中要求中间变量保持16位以上的精度,很多情况下是必须的。我发现VC6.0以及VS2003,双精度数据的最高精度是16位,某些情况下(比如自适应算法)这会降低程序的运行速度,比如用积分法计算伽玛函数,计算gamma(26.9)
mathematica4.2:
2.9065239044018627e+26
Dev-C++ 4.9.8.10:
2.906523904401857e+026
BCBX1.0:
2.906523904401856818e+26
VC6.0:
2.9065239043927034e+026而是用一下代码计算结果也有区别(算法本身提供的精度不高)long double GammaLn( long double x )
{
  if ( x < 0 ) exit( 0 );
  if ( x == 0 ) return 0;
  long double xbuf, y, tmp, ser;
  static long double cof[6] =
  {
    76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.001208650973866179, -0.000005395239384953
  };
  int i;
  y = xbuf = x;
  tmp = xbuf + 5.5;
  tmp -= ( xbuf + 0.5 ) * log( tmp );
  for ( ser = 1.000000000190015, i = 0; i <= 5; i++ )
  {
    y++;
    ser += cof[i] / y;
  }
  return ( -tmp + logl( 2.5066282746310005 * ser / xbuf ) );}//---------------------------------------------------------------------------
long double Gamma( long double x )
{
  long double temp1, temp2;
  if ( x < 0 )
  {
    if ( int( x ) == x ) return 1.0e300;
    temp1 = fabs( x );
    temp2 = expl( GammaLn( temp1 ) );
    return -PI / ( x * temp2 * sinl( PI * x ) );
  }
  else
    return ( expl( GammaLn( x ) ) );
}
结果是:
Dev-C++
2.906523904463532e+026
BCBX1.0
2.906523904463532204e+26
VC6.0
2.9065239044635298e+026VC在浮点数上需要进行某种设置吗?请朋友告知,谢谢!

解决方案 »

  1.   

    不搞数值计算的人可能不会注意这个问题。  
    在大部分情况下很多人不会用到小数点后16位,但是程序中要求中间变量保持16位以上的精度,很多情况下是必须的。  
     
    我发现VC6.0以及VS2003,双精度数据的最高精度是16位,某些情况下(比如自适应算法)这会降低程序的运行速度,比如用积分法计算伽玛函数,计算gamma(26.9)  
    mathematica4.2:  
    2.9065239044018627e+26  
    Dev-C++  4.9.8.10:  
    2.906523904401857e+026  
    BCBX1.0:  
    2.906523904401856818e+26  
    VC6.0:  
    2.9065239043927034e+026  
     
    而用一下代码计算结果也有区别(算法本身提供的精度不高)  
     
    long  double  GammaLn(  long  double  x  )  
    {  
       if  (  x  <  0  )  exit(  0  );  
       if  (  x  ==  0  )  return  0;  
       long  double  xbuf,  y,  tmp,  ser;  
       static  long  double  cof[6]  =  
       {  
           76.18009172947146,  -86.50532032941677,  24.01409824083091,  -1.231739572450155,  0.001208650973866179,  -0.000005395239384953  
       };  
       int  i;  
       y  =  xbuf  =  x;  
       tmp  =  xbuf  +  5.5;  
       tmp  -=  (  xbuf  +  0.5  )  *  log(  tmp  );  
       for  (  ser  =  1.000000000190015,  i  =  0;  i  <=  5;  i++  )  
       {  
           y++;  
           ser  +=  cof[i]  /  y;  
       }  
       return  (  -tmp  +  logl(  2.5066282746310005  *  ser  /  xbuf  )  );  
     
    }  
     
    //---------------------------------------------------------------------------  
    long  double  Gamma(  long  double  x  )  
    {  
       long  double  temp1,  temp2;  
       if  (  x  <  0  )  
       {  
           if  (  int(  x  )  ==  x  )  return  1.0e300;  
           temp1  =  fabs(  x  );  
           temp2  =  expl(  GammaLn(  temp1  )  );  
           return  -PI  /  (  x  *  temp2  *  sinl(  PI  *  x  )  );  
       }  
       else  
           return  (  expl(  GammaLn(  x  )  )  );  
    }  
     
     
    结果是:  
    Dev-C++  
    2.906523904463532e+026  
    BCBX1.0  
    2.906523904463532204e+26  
    VC6.0  
    2.9065239044635298e+026  
     
    VC在浮点数上需要进行某种设置吗?请朋友告知,谢谢!  
      

  2.   

    Double precision values with double type have 8 bytes. The format is similar to the float format except that it has an 11-bit excess-1023 exponent and a 52-bit mantissa, plus the implied high-order 1 bit. This format gives a range of approximately 1.7E–308 to 1.7E+308 for type double.Microsoft Specific —>The double type contains 64 bits: 1 for sign, 11 for the exponent, and 52 for the mantissa. Its range is +/–1.7E308 with at least 15 digits of precision. 
      

  3.   

    如果您的应用已经接近该浮点数的极限精度,
    您应该使用更高精度的浮点数,
    如果系统本身没有提供更高精度的浮点数,
    您可能需要自己实现。好象有一种 long double
      

  4.   

    The double type contains 64 bits: 1 for sign, 11 for the exponent, and 52 for the mantissa. Its range is +/–1.7E308 with at least 15 digits of precision. 即精度为 15 位.
      

  5.   

    谢谢各位的参与。从后面的代码中可以看出,我用的是long double数据类型,并且我说的也是关于long double类型的数据。one_add_one()我要睡觉:) 和sgnaw(李逍遥) 说的有关内容,intel的编译器帮助文件也有有关介绍。intel在浮点数处理上有另一套方案,好像是80bit存储。intel在其编译器的帮助文件中好像提到:VC的浮点数方案接近IEEE标准,这里指的是接近,看来不是完全符合IEEE标准。tryanother() 说的32位或64位浮点数,我不知道怎麽用,你能提供有关例子吗?