如何让Delphi货币类型一直像Excel一样回合?

时间:2012-06-10 01:21:58

标签: delphi excel format currency rounding

我正在努力让Delphi像Excel一样圆,但我不能。这是代码:

procedure TForm1.Button1Click(Sender: TObject);
var
 s : string;
 c : currency;
begin
 c := 54321.245;
 s := '';
 s := s + Format('Variable: %m',[c]);
 s := s + chr(13);
 s := s + Format('   Literal: %m',[54321.245]);
 ShowMessage(s);
end;

Delphi Rounding

我正在使用设置为54321.245的货币变量,当我格式化此变量时,它使用Bankers Rounding进行舍入。但是,当我将相同的值格式化为文字时,它会舍入Excel舍入的方式。

我预计这将转为 $ 54,321.25 无论是形成货币变量还是字面值。我怎样才能确保Delphi每次都以与Excel相同的方式进行舍入?

修改

The rounding I expect to see is as follows:  
54,321.245   = 54,321.25  
54,321.2449  = 54,321.24  
54,431.2499  = 54,421.25 

我只使用文字显示Delphi轮次的不同方式。我希望在实际代码中使用变量。

注意:
如果我将变量从货币更改为扩展,则会正确舍入

编辑#2

有人建议我不清楚我的要求,这绝对不是真的。我对我的要求有一个非常清楚的理解,我显然没有很好地解释它们。我想要的舍入方法是两位小数。当deimal部分具有千分之一值> = 0.005时,我希望它舍入到0.01,Delphi提供的货币类型不会这样做。我也试过这个例子,使用带有money数据类型的Microsoft SQL(我假设它与Delphi的货币相同),并且SQL按照我描述的方式对它进行了轮询。

  • SQL Money> = 0.005 = 0.01
  • 德尔福货币> = 0.005:= 0.00

编辑#3
好文章:http://rvelthuis.de/articles/articles-floats.html
可能的解决方案:http://rvelthuis.de/programs/decimals.html

编辑#4
以下是Embarcadero讨论的解决方案之一

function RoundCurrency(const Value: Currency): Currency;
var
  V64: Int64 absolute Result;
  Decimals: Integer;
begin
  Result := Value;
  Decimals := V64 mod 100;
  Dec(V64, Decimals);
  case Decimals of
    -99 .. -50 : Dec(V64, 100);
    50 .. 99 : Inc(V64, 100);
  end;
end;

4 个答案:

答案 0 :(得分:13)

如果我理解正确,你正在寻找:

function RoundTo2dp(Value: Currency): Currency;
begin
  Result := Trunc(Value*100+IfThen(Value>0, 0.5, -0.5))/100;
end;

答案 1 :(得分:6)

不可能让RTL按照您想要的方式进行。在Delphi中影响舍入的方法是使用SetRoundMode sets the FPU conrol word进行舍入,但据我所知,没有FPU支持将精确的中间舍入到向上舍入(这是通常避免,因为它会产生较高值的偏差。)

您必须实现自己的舍入功能。在Delphi Rounding thread上对Embarcadero论坛进行了广泛的讨论,其中包括几个解决方案。

答案 2 :(得分:1)

使用功能System.Math.SimpleRoundTo

答案 3 :(得分:0)

您可以通过以下方式控制delphi如何舍入数字:

uses Math;
...

procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
c : currency;
begin
 SetRoundMode(rmNearest);

 c := 54321.245;
 s := '';
 s := s + Format('Variable: %m',[c]);
 s := s + chr(13);
 s := s + Format('   Literal: %m',[54321.245]);
 ShowMessage(s);
end;

不幸的是,使用rmNearest,Delphi决定数字54321.245比54321.2更接近54321.24