2016-04-17 20 views
1

浮動小数点数を小数点以下第2位まで四捨五入する必要がありますが、常に下げてください。今私はRoundTo(number, -2)を使用していますが、私の状況では望ましくない動作であり、数学的に正しく丸めます。Delphi - RoundTo - always down

var a,b: currency; 
    floatStr: string; 
    format: TFormatSettings; 
    localeDec: char; 
begin 


    format:= TFormatSettings.Create; 
    localeDec:= format.DecimalSeparator; 
    format.DecimalSeparator:= ','; 
    System.SysUtils.FormatSettings:= format; 

    a:= 2/30; 
    floatStr:= floatToStr(a); 
    b:= strToCurr(
     copy(floatStr, 1, ansiPos(',', floatStr) + 2) 
); 
    showMessage(currToStr(b)); 

    format.DecimalSeparator := localeDec; 
    System.SysUtils.FormatSettings:= format; 

end; 

しかし、この解決策はちょうどいい感じていない:私は最終的にこれを使用してそれを達成

...私はさておき、これを実行する必要がある理由、してみましょう。文字列をつぶしたり、小数点区切り文字をリセットしたりすることなく、「数学的にきれいな」方法がありますか?私は多くを探しましたが、何も見つかりませんでした。

答えて

4

は、次の操作を行うことができます。

  1. 乗算値を100
  2. 切り捨てて整数に、ゼロに向かって。
  3. このように100

除算値を:私は切り捨てあなたがゼロに向かって意味と仮定してきた

function RoundCurrTo2dpTruncate(const Value: Currency): Currency; 
begin 
    Result := Trunc(Value*100)/100; 
end; 

。したがって、0.678は0.67と-0.678から-0.67に丸められます。ただし、-∞に丸めたい場合はTruncFloorに置き換えてください。問題に取り組むため

function RoundCurrTo2dpDown(const Value: Currency): Currency; 
begin 
    Result := Floor(Value*100)/100; 
end; 

別の方法は、Currency値は単にそのため全体の動作を使用する上記のコードとは異なり、整数演算を用いて行うことができる10000の暗黙的なシフトを有する64ビット整数であることを認識することです浮動小数点演算。 documentationから

通貨金融計算における丸め誤差を最小に固定小数点データ・タイプです。これは、スケールされた64ビット整数として格納され、暗黙的に小数点以下を表す4桁の最下位桁が格納されます。ここでの算術れている

function RoundCurrTo2dpTruncate(const Value: Currency): Currency; 
begin 
    PInt64(@Result)^ := (PInt64(@Value)^ div 100)*100; 
end; 

注:割り当てや式で他の実数型と混在させた場合は、あなたがこのようなRoundCurrTo2dpTruncateを実装することができますたとえば、通貨の値が自動的に10000

で割ったり掛けされています10000だけシフトされています。したがって、100の乗算は100で除算されています。あなたが古いデルファイRoundToで

SetRoundMode(rmDown); 

function RoundTo(const AValue: Double; const ADigit: TRoundToRange): Double; 
var 
    LFactor: Double; 
begin 
    LFactor := IntPower(10, ADigit); 
    Result := Round(AValue/LFactor) * LFactor; 
end; 

をSetRoundModeを使用することができます

+0

最近のバージョンで変更されました。 – kludg

+3

@ user246408私は実際に整数演算を使ってすべてを行う方が良いと思います。 –

0

もちろん、それは私がTrunc`が潜在的にオーバーフローする `のでInt`がTrunc``よりも優れている `信じる

+0

ええ、私は間違っています。それでも疑問は「通貨」です。 –

+0

はい、それは適切ではありません。私は最初の部分を「小数点以下2桁までの浮動小数点数を丸める」だけを読んだ。 – smooty86

+0

十分な公正。 Askerはちょっと混乱しています。通貨は固定小数点です。 –