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;

Delphi 丸め

54321.245 に設定された通貨変数を使用しています。この変数をフォーマットすると、銀行の丸めを使用して丸められます。ただし、同じ値をリテラルとしてフォーマットすると、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

私の要件を明確に理解していないと示唆する人もいますが、これはまったく真実ではありません。私は自分の要件を非常に明確に理解していますが、明らかにそれらをうまく説明できていません。私が望む丸め方法は、小数点以下2桁です。小数部分が 1000 分の 1 の値 >= 0.005 の場合、0.01 に丸めたいのですが、Delphi が提供する通貨タイプではこれが行われません。また、Microsoft SQL を money データ型 (Delphi の通貨と同じであると想定) で使用して、この例を試してみました。

  • SQL マネー >= 0.005 = 0.01
  • デルファイ通貨 >= 0.005 := 0.00

編集 #3
良い記事: http://rvelthuis.de/articles/articles-floats.html
考えられる解決策: http://rvelthuis.de/programs/decimals.html

編集#4
これは、エンバカデロの議論からの解決策の1つです

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 で丸めに影響を与える方法は、FPU 制御ワードを丸めに設定するSetRoundModeを使用することですが、私が知る限り、正確な中間を上向きに丸めるための FPU サポートはありません (これは一般的に回避されます。より高い値へのバイアス)。

独自の丸め関数を実装する必要があります。Embarcadero フォーラムのDelphi Rounding スレッドには、いくつかの解決策を含む広範な議論があります。

于 2012-06-10T14:07:10.233 に答える
0

次の方法で、デルファイの丸め数値を制御できます。

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 に答える