2016-05-06 15 views
2

「sum」という小数点があり、その値は5824088.999120mですが、小数点以下3桁に丸めようとすると5824088.999mの代わりに5824088.998mが得られます。それは5824088.999mを残す代わりに減少します。十進数が正しく丸められない

なぜですか?ここに私のコードです:

List<decimal> quantityList = QuantityList(); 
List<decimal> priceList = PriceList(); 

decimal destination = 5824088.999M; 
decimal sum = 0M; 
bool lifesaver = false; 

for (int x = 0; x < priceList.Count; x++) 
{ 
    sum = 0M; 
    for (int i = 0; i < 3500; i++) 
    { 
     priceList[x] += 0.001M; 
     sum = 0M; 
     for (int y = 0; y < priceList.Count; y++) 
     { 
      decimal multipleProduct = priceList[y] * quantityList[y]; 
      sum = sum + multipleProduct; 
      Console.WriteLine(priceList[y] + " " + quantityList[y]); 

      sum = Math.Round(sum, 3); 
      Console.WriteLine("Sum: " + sum); 
      Console.ReadKey(); 
      Console.WriteLine(); 
     } 

     if (sum == destination) 
     { 
      Console.WriteLine("The new number is " + priceList[x] + " and it is the {0} element!", x); 
      lifesaver = true; 
      break; 
     } 
     else if (sum > destination) 
     { 
      Console.WriteLine("Limit exceeded!"); 
     } 

     if (i == 3499) 
     { 
      priceList[x] -= 3.500M; 
     } 
     if (lifesaver == true) 
     { 
      break; 
     } 
    }//Second for loop 

    if (lifesaver == true) 
    { 
     break; 
    } 
}//Main for loop 

リストは別の方法です。

答えて

3

あなたがエラー蓄積切り上げるため、合計が間違って持っているようだ:

for (int y = 0; y < priceList.Count; y++) { 
    ... 
    sum = Math.Round(sum, 3); // <- this accumulates round up errors 
    ... 
    } 

がすべて1のです

priceList = new List<Decimal>() { 
    1.0004M, 1.0004M, 1.0004M}; 

quantityListながらpriceListが含まれていることを想像します。実際の合計が

Math.Round(1.0004M + 1.0004M + 1.0004M, 3) 

3.001Mであるsum

1.000M, 2.000M, 3.000M 

あろう。 可能な救済策が早期を切り上げされていません。

for (int y = 0; y < priceList.Count; y++) { 
     ... 
     //DONE: comment out this: no premature rounding (within the loop) 
     // sum = Math.Round(sum, 3); 
     //DONE: but format out when printing out 
     Console.WriteLine("Sum: {0:F3}", sum); 
     ... 
    } 

    // round up (if you want) after the loop 
    sum = Math.Round(sum, 3); 
+0

@Reza Taibur:*削除/コメントアウト* 'sum = Math.Round(sum、3);' - ループ内で*を早期に切り捨てないでください。 。切り上げたい場合は、*ループの後に* –

+0

ありがとう!ループで丸められませんでした! –

0

MidpointRounding(https://msdn.microsoft.com/en-us/library/system.midpointrounding(v=vs.110).aspx)を調べ、これをMath.Round関数に追加する必要があります。このように:sum = Math.Round(sum, 3, MidpointRounding.ToEven);、あなたが持っているもう1つのオプションはMidpointRounding.AwayFromZeroです。

+1

まあ、私はAwayFromZeroを使用することは、ToEvenとは異なる方法でラウンドすると確信しています。もしあなたがそれを試してみたら、あなたがしたことと結果が何であったかを教えてください。あなたが試したこととしなかったことを皆が知っていることだけを期待することはできません。 "うまくいきませんでした。私はすでにそれを試しました。"という答えにはまともな回答ではありません。 –

0

それが原因Math.Round方法です。 MSDN documentation

この方法はMidpointRounding.ToEven.When dのモード引数ラウンド(進数、のInt32、MidpointRounding)メソッドを呼び出すことと等価である正確半2つの丸められた値の間、結果が有する丸めた値であります右端の小数点位置の偶数桁。たとえば、2小数点以下に切り上げると、値2.345は2.34になり、値2.355は2.36になります。このプロセスは、均等に丸める、または銀行家の丸めとして知られています。単一方向の中点値を一貫して丸めることによって生じる丸め誤差を最小限に抑えます。

あなたはhere

を見つけることができMath.Round(decimal, int32, System.MidpointRounding)は、MidPointRounding列挙AwayFromZero値でそれを呼び出してみてみてください。

例:発言から

decimal d = 5824088.999120M; 
decimal rounded = Math.Round(d, 3, System.MidpointRounding.AwayFromZero); 
Console.WriteLine(rounded.ToString()); 

ログ5824088.999

小数パラメータは、戻り値の大幅な小数点以下の桁数を指定した場合は0から28までの範囲小数点以下がゼロの場合、整数が返されます。

中点の値では、結果の最下位桁の後の値は、2つの数値の間の正確な中間です。たとえば、小数点以下第二位を四捨五入する場合は3.47500を中点値にし、整数に四捨五入する場合は7.500を中点値にします。このような場合、最も近い値はモード引数で指定された丸め規則なしでは容易に識別できません。 Round(Decimal、Int32、MidpointRounding)メソッドは、中間点値を処理するための2つの丸め規則をサポートしています。

ゼロから丸めます。 中点の値は、ゼロから次の数値に丸められます。例えば、3.75ラウンドから3.8ラウンド、3.85ラウンドから3.9ラウンド、-3.75ラウンドから-3.8ラウンド、および-3.85ラウンドから-3.9ラウンド。このフォームの丸めは、MidpointRounding.AwayFromZero列挙メンバーによって表されます。 ゼロからの丸めは、最も広く知られている丸めの形式です。

均等に丸めたり、バンカーが丸めたりする 中点の値は、最も近い偶数に丸められます。たとえば、3.75と3.85の両方が3.8に丸められ、-3.75と-3.85の両方が-3.8に丸められます。この丸めの形式は、MidpointRounding.ToEven列挙メンバで表されます。 最も近い値への丸めは、財務および統計処理で使用される標準的な丸め形式です。複数の丸め演算で使用する場合、一貫して中点値を1つの方向に丸めることによって発生する丸め誤差を低減します。場合によっては、この丸め誤差が大きくなることがあります。

これもチェックしてください.NET fiddleあなたがそれを実行すると、あなたの期待値が正確に表示されます5824088.999

+0

私は最終的に合計が.000でない正確な値が必要です –

+0

@RezaTaibur私はあなたが必要とするものを理解できないのでしょうか?私たちがあなたを助けることができるように、あなたの質問に正確に必要なものを明確にしてください。 – gdyrrahitis

+0

ありがとうございますが、私はすでに答えを得ています(Dmytri Bychenkoの答えを参照) –

関連する問題