2009-07-15 116 views
57

在C#中這些線調整小數精度,.NET

decimal a = 2m; 
decimal b = 2.0m; 
decimal c = 2.00000000m; 
decimal d = 2.000000000000000000000000000m; 

Console.WriteLine(a); 
Console.WriteLine(b); 
Console.WriteLine(c); 
Console.WriteLine(d); 

生成的輸出:

2 
2.0 
2.00000000 
2.000000000000000000000000000 

所以我可以看到,創建從文字小數變量可以讓我來控制的精度。

  • 我可以在不使用文字的情況下調整小數變量的精度嗎?
  • 如何從a創建b?我怎樣才能從c創建b?

回答

44

保留像這樣的尾隨零是在.NET 1.1中引入的,用於更嚴格地符合ECMA CLI規範。

在MSDN上有這方面的信息,例如: here

可以按如下方式調整精度:

  • Math.Round(或天花板,地板等)由1.000下降精密(B c)從

  • 乘...(用你想要的小數位數)來提高精度 - 例如乘以1.0M從a得到b。

17

您只會看到完全相同數據的不同表示。 decimal的精確度將被縮放爲與需要的一樣大(在合理範圍內)。

System.Decimal

的十進制數是一個浮點 值,它由一個符號,一個 數字值,其中在 值的每個數字範圍從0到9的,和一個 比例因子,表示浮點小數點 的 位置,該位置將積分和 數字值的小數部分分開。

一個十進制 值的二進制表示由一個1位的符號,一個 96位整數,用來劃分96位 整數,並指定其什麼部分的縮放 因子 是一個小數部分。縮放因子 是隱式地升高到一個指數取值範圍爲0到 28.因此,10號, ,一個十進制值的二進制 表示是所述形式,((-2 到的 )/ 10 (0至 28)),其中-2 -1等於 MINVALUE,和2 -1等於 MaxValue的。

縮放因子還保留任何 十進制數中的尾隨零。 尾數零不會影響算術或比較操作中的一個十進制數的 值。 但是,如果應用了 適當的格式字符串,則尾部零可以是由ToString方法顯示的 。

+1

有關比例因子的好信息...現在我該如何調整它? – 2009-07-15 17:33:14

+1

縮放因子不可直接控制,因爲它根據指數的大小進行調整。這基本上是浮點運算(以及術語「浮動」來自何處)的原理。由於有效位的位數是常數,因此數的大小決定了有效位的位數。 – codekaizen 2009-07-15 17:57:07

+0

它會自動調整以適應其包含的數據需求。是否有一個特定的原因需要手動縮放它? – 2009-07-15 17:58:37

1

問題是 - 你是否真的需要精度爲存儲在在十進制,而不是隻顯示小數到所需的精度。 大多數應用程序內部知道他們想要的精度和顯示精度。例如,即使用戶在帳戶包中輸入100的發票,它仍然會使用類似val.ToString(「n2」)的值打印爲100.00。

如何從a創建b?我怎樣才能從c創建b?

c to b is possible。

Console.WriteLine(Math.Round(2.00000000m, 1)) 

產生2.0

a到b是棘手,因爲引入精度的概念是一個小外星人數學。

我想一個可怕的黑客可能是一次往返。

decimal b = Decimal.Parse(a.ToString("#.0")); 
Console.WriteLine(b); 

產生2.0

5

我發現我能「篡改」隨着規模乘以或看上分割1.

decimal a = 2m; 
decimal c = 2.00000000m; 
decimal PreciseOne = 1.000000000000000000000000000000m; 
    //add maximum trailing zeros to a 
decimal x = a * PreciseOne; 
    //remove all trailing zeros from c 
decimal y = c/PreciseOne; 

我可以製造一個足夠精確的1改變規模因素已知的大小。

decimal scaleFactorBase = 1.0m; 
decimal scaleFactor = 1m; 
int scaleFactorSize = 3; 

for (int i = 0; i < scaleFactorSize; i++) 
{ 
    scaleFactor *= scaleFactorBase; 
} 

decimal z = a * scaleFactor; 
5

人們很容易在.NET混淆decimal在SQL Server與decimal;他們完全不同。

SQL Server decimal是一個定點數,當定義列或變量時,其精度和比例是固定的。

甲.NET decimal是像floatdouble一個浮點數(不同之處在於decimal準確保留十進制數字而floatdouble準確保存二進制數)。試圖控制.NET的精確度是毫無意義的,因爲無論是否存在填充零,所有計算結果都會得到相同的結果。

-1

這將刪除小數點後的所有尾隨零,然後您可以使用ToString()

public static class DecimalExtensions 
{ 
    public static Decimal Normalize(this Decimal value) 
    { 
     return value/1.000000000000000000000000000000000m; 
    } 
} 

或者,如果你想尾隨零的一個確切的數字,說5,第一規格化(),然後乘以1.00000米。