2

私が書いたクエリに問題があります。何らかの理由で、小数点以下の値を格納するために使用している変数が、小数点以下6つの値を返します(ほとんどは0です)。

私は運が悪かったので、以下(およびMath.Roundを使用したさまざまな組み合わせ)を試しました。

Sales =
          (from invhed in INVHEAD 
           ... // Joins here
           orderby cust.State ascending
           select new Sale
           {
                InvoiceLine = inv.InvoiceLine,
                InvoiceNum = inv.InvoiceNum,
                ...
                NetPrice = Math.Round((inv.ExtPrice - inv.Discount) * (Decimal) (qsales.RepSplit / 100.0), 2, MidpointRounding.ToEven),
           }).ToList<Sale>();

NetPriceメンバーには、300.000000、5000.500000、3245.250000などの値があります。

手がかりはありますか?この問題についてオンラインで何も見つからないようです。

編集:

Decimal.Roundがトリックを実行しました(NetPriceメンバーがDecimalタイプであることに言及するのを忘れました)。以下の私の答えを参照してください。

4

3 に答える 3

2

末尾のゼロは、10進型の.ToStringの出力に表示される場合があります。正しいフォーマット文字列を使用して、表示する小数点以下の桁数を指定する必要があります。例えば:-

 var s = dec.ToString("#.00");

小数点以下2桁を表示します。

内部的には、decimal型は整数と10進数のスケーリング係数を使用します。末尾の0を生成するスケーリング係数。スケーリング係数が2の小数点タイプから始めると、0であっても小数点以下2桁になります。

小数を加算および減算すると、関係する小数の最大値であるスケーリング係数を持つ小数になります。したがって、スケーリング係数が2の小数を同じ結果の小数から別の小数から減算すると、係数も2になります。

小数の乗算と除算は、2つの小数オペランドのスケーリング係数の合計であるスケーリング係数を持つ小数になります。小数にスケーリング係数2を掛けると、スケーリング係数4の新しい小数になります。

これを試して:-

var x = new decimal(1.01) - (decimal)0.01;
var y = new decimal(2.02) - (decimal)0.02;
Console.WriteLine(x * y * x * x);

あなたは2.00000000を取得します。

于 2009-09-04T20:25:32.313 に答える
2

System.Decimal設計により後続ゼロを保持します。言い換えると、1m1.00mは2つの異なるdecimalsであり(ただし、等しいと比較されます)、小数点以下の桁数が異なるように丸められていると解釈できます。たとえば、Math.Round(1.001m)を与え1mMath.Round(1.001m, 2)を与え1.00mます。算術演算子はそれらを異なる方法で処理します-+そして-、それらのほとんどを持っているオペランドと同じ桁数(so 1.50m + 0.5m == 1.10m)を持ち*/それらのオペランドの桁数の合計(so)を持つ結果を生成します1.00m * 1.000m == 1.00000m

于 2009-09-04T20:36:33.303 に答える
0

以前と同じ引数でDecimal.Round()を使用して動作させることができました。:)

この問題は、Pavelが言っていたことの軌跡にあるように見えます。ここでは、Decimalタイプの動作が異なり、Math.Roundは、期待どおりに機能しません...

すべての入力をありがとう。

于 2009-09-04T20:47:32.113 に答える