10

我正在尝试让 Delphi 像 Excel 一样进行 Round,但我做不到。这是代码:

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;

德尔福四舍五入

我正在使用设置为 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

有人说我对自己的需求没有清晰的认识,这绝对不是真的。我对自己的要求有非常清楚的了解,我显然没有很好地解释它们。我想要的舍入方法是两位小数。当小数部分的千分之一值 >= 0.005 我希望它四舍五入到 0.01 时,Delphi 提供的货币类型不会这样做。我还尝试了使用 Microsoft SQL 和货币数据类型(我假设它与 Delphi 的货币相同)的这个示例,并且 SQL 按照我描述的方式对其货币类型进行舍入。

  • SQL 金钱 >= 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

4 回答 4

16

如果我理解正确,您正在寻找这个:

function RoundTo2dp(Value: Currency): Currency;
begin
  Result := Trunc(Value*100+IfThen(Value>0, 0.5, -0.5))/100;
end;
于 2012-06-10T16:24:23.163 回答
6

不可能使 RTL 以您想要的方式四舍五入。在 Delphi 中影响舍入的方法是使用SetRoundModewhich设置 FPU 控制字进行舍入,但是,据我所知,没有 FPU 支持将精确的中间值向上舍入(这通常是避免的,因为它会生成偏向更高的值)。

您必须实现自己的舍入功能。Embarcadero 论坛上的Delphi Rounding 线程中有一个扩展讨论,其中包括几个解决方案。

于 2012-06-10T14:07:10.233 回答
1

使用函数 System.Math.SimpleRoundTo

于 2019-08-12T09:42:54.563 回答
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.25 更接近 54321.24

于 2012-06-10T04:17:03.887 回答