2011-03-29 40 views
5

我希望能夠從System.Decimal值中得到位,然後將其轉換爲值的字符串表示形式,很像Decimal.ToString()會做的,但我很難提出該算法。如何將System.Decimal位轉換爲C#中的字符串?

所以我有這樣的事情:

decimal d = 1403.45433M; 
int[] nDecimalBits = decimal.GetBits(d); 

// How to convert the 4 integers in nDecimalBits to a string 
// that contains "1403.45433"? 

我知道小數的二進制佈局 - 前3個整數包含值位和最後一個整數包含符號位,比例因子。

我試着搜索使用各種搜索術語的算法,但十進制主要用作'浮點數'的同義詞,所以我的搜索找到了無關問題的答案。

任何幫助,將不勝感激。

編輯:爲了迴應一些答案,我需要將這些位發送到需要重構值的不同平臺。 System.Decimal及其任何成員函數在那裏都不可用,所以我需要獲取這些位並將它們轉換爲字符串。

如果我有選擇,我顯然使用ToString(),但我不需要問。

+0

爲什麼你需要做到這一點,你爲什麼不能使用「十進制的ToString()「? – 2011-03-29 08:16:25

回答

1

既然你不能使用ToString(),你可能想看看單開發商如何實現這一點:

入口點是NumberToString(string, decimal, IFormatProvider)

有趣的是InitDecHexDigits(uint, ulong),這被稱爲像這樣

InitDecHexDigits ((uint)bits [2], ((ulong)bits [1] << 32) | (uint)bits [0]); 

並執行「位雜耍和轉移」的事到三個整數轉換成binary coded decimals_val1 to _val4),然後可以(平凡)轉換成一個字符串。

(不要誤會的事實,他們稱之爲「十六進制表示」它的二進制編碼的十進制數字。混淆)

+0

Heinzi,謝謝 - 我沒有想到這一點。我會檢查一下,這可能正是我所尋找的。就我的目的而言,BCD幾乎與直線字符串一樣好,而從BCD開始,字符串轉換是微不足道的,就像你說的那樣。再次感謝您的幫助。 – xxbbcc 2011-03-30 08:20:28

3

這不算,但我想它應該有所幫助。

十進制位structure

一個十進制 數目的二進制表示由一個1位的符號,一個 96位整數,用來劃分整數 數目的縮放 因子並指定它的什麼部分 是一個小數部分。縮放因子 是隱式地升高到一個指數取值範圍爲0到 28.

返回值數目爲10, 是四元件 陣列的32位帶符號的整數。

第一,返回的數組的 第二和第三元素包含低, 中間和96位 整數的高32位。

返回的 數組的第四個元素包含比例因子和 符號。它由以下部分組成 部分:

位0到15,低位字,是 未使用且必須爲零。

位16至23必須包含0和28之間的指數 ,其指示 功率的10分割整數 數。

位24到30未使用,必須爲 零。

位31包含符號; 0表示 正數,1表示負數。

+0

謝謝你的回答 - 我已經有了這些細節。我可以進行二進制到字符串的轉換,但十進制是一個更復雜的情況(高位整數中的位需要移位,因爲低位整數中的位被處理),我還找不到解決方案。 – xxbbcc 2011-03-30 04:37:44

+0

@xxbbcc:我不知道爲什麼這不能幫助你...它正確地描述了Decimal在整數數組中的存儲格式。我猜算法非常簡單:將前三個整數連接成一個大整數數據類型(例如Java的BigInteger類型),然後使用第四個整數來確定放置小數點的位置。如果您在確定算法時告訴我們您卡在哪裏,可能會有所幫助。 – Heinzi 2011-03-30 07:10:07

+0

我正在處理一個非常緊迫的截止日期,目標平臺上的小數支持在最後一分鐘被拋出。在轉換過程中,我必須保留所有的十進制數字,所以使用double是沒有問題的 - 舍入誤差(十進制本身之外)是不允許的,所以我必須在進行直接十進制到字符串轉換時輸入位。以正確的位數移位是卡住的地方--int32是我在轉換過程中可以使用的最大數字類型。 – xxbbcc 2011-03-30 08:35:16

6

可以使用十進制構造Decimal(Int32[])到你的價值轉換回:

十進制構造函數(的Int32 [])

初始化十進制的新實例,以表示一個十進制值二進制幷包含在指定的數組中。

之後,如果需要,可以使用ToString。 例如:

decimal d = 1403.45433M; 
int[] nDecimalBits = decimal.GetBits(d); 

decimal d2 = new decimal(nDecimalBits); 
string s = d2.ToString(); 
+1

+1:沒有理由在這裏重新發明輪子。使用小數構造函數將這些位轉換回小數點。 – 2011-03-29 08:24:44

+0

您還沒有看到我的消息。我沒有一個奇怪的衝動來重新發明輪子 - 我需要在.NET不可用的平臺上重建小數點的字符串值。我所擁有的是從服務器的小數點中得到的4個整數。我可以發送文本而不是4個整數,但我需要儘量減少網絡流量。 – xxbbcc 2011-03-30 04:34:05

+1

@xxbbcc:我已閱讀您的消息... .NET FW在目標平臺上不可用的信息是新的。 ;-)這可能有助於瞭解*目標平臺上可以使用哪種技術。在Java中實現這樣的算法(參見我對Bugai13的答案的評論)可能比例如在C中容易得多。我已經添加了第二個答案,其中包含單聲道實現的鏈接,該實現僅使用uint/ulong數據類型,一些位移魔術。 – Heinzi 2011-03-30 08:12:32

2

是否有任何主要原因,你不能只使用小數構造函數?

new decimal(nDecimalBits).ToString(); 
+0

這是真的,但似乎他不喜歡ToString,他希望從位(提取96位int值,指數,符號)建立十進制字符串。 – 2011-03-29 08:16:07

相關問題