簡體   English   中英

C#十進制舍入不一致嗎?

[英]Is C# Decimal Rounding Inconsistent?

我一直在使用來自SQL Decimal(38,30)的C#中的十進制精度,我終於完成了一個舍入奇怪的方法。 我知道我可能會忽視這里顯而易見的事情,但我需要一點見解。

我遇到的問題是C#沒有產生我認為是一致輸出的東西。

decimal a = 0.387518769125m;
decimal b = 0.3875187691250002636113061835m;

Console.WriteLine(Math.Round(a, 11));
Console.WriteLine(Math.Round(b, 11));
Console.WriteLine(Math.Round(a, 11) == Math.Round(b, 11));

產量

0.38751876912
0.38751876913
False

嗯,0.38751876913? 真? 我在這里錯過了什么?

來自MSDN

如果小數位的數字是奇數,則將其更改為偶數。 否則,它保持不變。

為什么我看到不一致的結果? 額外的精度不會改變'小數位數'......

來自MSDN:

如果decimals右邊d有一個非零數字 且其值為5 ,則小數位的數字如果是奇數則向上舍入,如果是偶數則保持不變 如果d的小數位數小於decimals ,則返回d不變。

在你的第一個案例

decimal a = 0.387518769125m;
Console.WriteLine(Math.Round(a, 11));

第11位右邊一位數字該數字為5 因此, 由於位置11是偶數,所以它保持不變 因此,你得到

0.38751876912

在你的第二個案件

decimal b = 0.3875187691250002636113061835m;
Console.WriteLine(Math.Round(b, 11));

第11位右邊沒有一位數字 因此,這是直接的小學 - 學校四舍五入; 如果下一個數字大於4,則向上舍入,否則向下舍入。 由於第11位右邊的數字超過4(它是5),我們會向上看,所以你看

0.38751876913

為什么我看到不一致的結果?

你不是。 結果與文檔完全一致。

從MSDN - Math.Round方法(十進制,Int32)

如果在十進制小數位右邊的d中有一個非零數字且其值為5,則小數位的數字如果是奇數則向上舍入,如果是偶數則保持不變。 如果d的小數位數小於小數位數,則返回d不變。

此方法的行為遵循IEEE標准754第4節。這種舍入有時稱為舍入到最近,或者是銀行家的舍入。 它最大限度地減少了在單個方向上始終舍入中點值所導致的舍入誤差。

注意使用單個非零數字 這對應於您的第一個示例,但不是第二個示例。

和:

若要控制Round(Decimal,Int32)方法使用的舍入類型,請調用Decimal.Round(Decimal,Int32,MidpointRounding)重載。

“小數位小數點右側d中的單個非零數字及其值為5”部分解釋了結果。 只有當圓形部分正好為0.5時,才能使用舍入規則。

讓我們將兩個數字都移到左邊11位數:

38751876912.5
38751876912.50002636113061835

使用銀行家的四舍五入,我們將第一個四舍五入。 每個中點舍入系統下,我們將第二個數字向上舍入(因為它不在中點)

.Net正在做我們期望的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM