首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

Delphi Trunc函数精度的有关问题,能解答送200分

2012-02-09 
Delphi Trunc函数精度的问题,能解答送200分vara,b,c,d:Doublei:Integerbegina:0.3b:0.3c:300000d:

Delphi Trunc函数精度的问题,能解答送200分
var
  a   ,   b,   c   ,d   :   Double;
  i   :   Integer;
begin
  a   :=   0.3;
  b   :=   0.3;
  c   :=   300000;

  d   :=   a   *   b   *   c;
  i   :=   Trunc(d);//26999不是   27000
  Memo1.Lines.Add( 'd   :=   a   *   b   *   c;   i   :=   Trunc(d)= '+IntToStr(i));
  i   :=   Trunc(d     *   10000);//269999999   不是   270000000
  Memo1.Lines.Add( 'd   :=   a   *   b   *   c;   i   :=   Trunc(d)= '+IntToStr(i));
end;

怎么才能让Trunc得到我想要的精度?
尝试在trunc前加一个很小的值

  d   :=   d+   1e-11;
  i   :=   Trunc(d);
有效
  d   :=   d+   1e-12;
  i   :=   Trunc(d);
则仍然有刚才的问题。

其他语言,例如c、c#尝试同样数值的乘法并取整没有这种问题。
浮点数精度上有问题但总觉得round有差异是可以理解,怎么在delphi中一个很正常的数取整也有问题呢?
---
c中测试浮点数表示值
union   D
{
double   f   ;
struct
{
unsigned   char   x1   ;
unsigned   char   x2   ;
unsigned   char   x3   ;
unsigned   char   x4   ;
unsigned   char   x5   ;
unsigned   char   x6   ;
unsigned   char   x7   ;
unsigned   char   x8   ;
}   ;
}   u,v   ;
      double   a   =   0.3;
      double   b   =   0.3;
      double   c   =   300000;
      u.f=a*b*c;
printf( "u.f=%30.20f\n ",u.f);
printf(   "%2x   %2x   %2x   %2x   %2x   %2x   %2x   %2x\n ",u.x8,u.x7,u.x6,u.x5,u.x4,u.x3,u.x2,u.x1)   ;

u.f=         27000.00000000000000000000
40   da   5e     0     0     0     0     0

---
c#测试相关代码
                        double   a   =   0.3;
                        double   b   =   0.3;
                        double   c   =   300000;
                        double   d   =   a   *   b   *   c;
                        this.textBox1.Text   =   Convert.ToInt32(Math.Truncate(d)).ToString();

能解答送200分

[解决办法]
请把 Double换成
Extended类型
[解决办法]
在计算机中浮点数的表达是近似值,a*b*c是近似=27000,而这里刚好得到的是26999.999999999996362,所以出现了Trunc(d)=26999的情况,为避免这种情况出现,
特别是在金融等的计算上面,往往需要限定d的精度,否则会出现这种微小的误差,而这误差累积起来,就会出现大的bug。a,b,c可以是double,但是结果不能用高精度的类型,设置为低精度的Single或者Currency类型可以很好的来避免。

热点排行