2012-06-14 10 views
13

Chciałbym przekonwertować dziesiętny na ciąg, z przecinkami jako tysiące separatory i zachować taką samą dokładność, z jaką został utworzony dziesiętny. (Będzie miał 2-5 cyfr znaczących)Format dziesiętny z przecinkami, zachowaj zera końcowe

 decimal d = 1234.4500M; 

     //I'd like "1,234.4500" 

     var notRight = d.ToString("###,###.#######");  //1,234.45 
     var alsoNotRight = d.ToString("###,###.00000");; //1,234.45000 
     var notRightEither = d.ToString("N"); //1,234.45 
     var notRightEither2 = d.ToString("G"); //1234.45000 

Czy nie ma wbudowanych w to zrobić, bez ręcznego analizowania ciąg? Jeśli nie ma jednego ciągu formatu, jaki jest najprostszy sposób to zrobić?

+0

Postanowiłem sprawdzić, jak formatowanie jest wykonywane. Niestety, podnoszenie ciężarów nie jest zarządzanym kodem (nic dziwnego), patrząc na [Standardowy format liczbowy] (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#GFormatString) wygląda tak, jakby był tylko "G "(domyślnie) zachowuje odstępy. – Guvante

Odpowiedz

12

Zgodnie z documentation, liczba dziesiętna zachowuje końcowe zera. Możesz je wyświetlić, jeśli użyjesz specyfikatora "G" lub w ogóle żadnego specyfikatora. Są one tracone, gdy używasz jednego ze specyfikatorów, który zawiera tysiąc separatora.

Jeśli chcesz określić liczbę zer przy konwersji do łańcucha, można to zrobić poprzez dodanie a precision specifier (od 0 do 99 cyfr) po znaku formatu, tak:

decimal d=1234.45M; 
var numberAsString=d.ToString("N4"); 

wynik będzie być

1,234.4500 

UPDATE: można uzyskać liczbę cyfr po przecinku, stosując metodę Decimal.GetBits która zwraca binarnej reprezentacji liczby. Liczba miejsc dziesiętnych jest przechowywana w bitach 16-23 (trzeci bajt) czwartego elementu.

The fourth element of the returned array contains the scale factor and sign. It consists of the following parts:

...

Bits 16 to 23 must contain an exponent between 0 and 28, which indicates the power of 10 to divide the integer number.

Pierwsze reprezentacją ciąg używając wszystkich cyfr można zrobić tak:

decimal d=1234.45000M; 
var nums=Decimal.GetBits(d); 
var decimals=BitConverter.GetBytes(nums[3])[2]; 
var formatStr="N"+decimals; 
d.ToString(formatStr); 

która będzie produkować

1,234.45000 
+0

Jesteś częściowo niepoprawny. Chociaż debugger pokaże, że wartość dziesiętna wynosi 1234.45, końcowe 0 są zachowane. Spróbuj użyć następującego kodu, na przykład: "dziesiętny d = 1234.4500M;' 'Console.WriteLine (d); // wyprowadza 1234.4500 ". –

+1

Twoja odpowiedź obejmuje tylko przykład, w którym liczba ma dokładnie 4 miejsca dziesiętne. Uważam, że stara się zachować oryginalną liczbę miejsc po przecinku (2-5). –

+1

Format jest określany jako liczba podzielona przez potęgę 10. Z tego powodu może on przechowywać 12345/100 lub 1234500/10000 odrębnie. – Guvante

1

Ponieważ planujesz mieć zmienną liczbę miejsc po przecinku (2-5), nie sądzę, że możesz ją ściągnąć za pomocą formatu ciągów.

To rozwiązanie nie jest konieczne, ale wykonuje swoją pracę. Zauważ, że przydzieli on kilka ciągów w procesie (jak sądzę 5), więc może nie działać dobrze na dużą skalę. Zachowasz liczbę miejsc dziesiętnych i otrzymasz grupy oddzielone przecinkami w części przed separatorem dziesiętnym.

+0

Możesz wyodrębnić liczbę cyfr z binarnej reprezentacji dziesiętnej i skonstruować ciąg formatujący z poprawną liczbą cyfr. –

+0

Używasz również separatorów specyficznych dla kultury, co oznacza, że ​​Twój kod złamie się, jeśli zostanie użyty w kulturze, która używa " , "w przypadku miejsc dziesiętnych, takich jak Francja, Niemcy, Hiszpania, Włochy, Grecja, Republika Południowej Afryki –

+0

Podoba mi się - jest to łatwe do zrozumienia kodu od razu. Chociaż można uzyskać indeks poza granicami, jeśli wartość nie ma elementu dziesiętnego (np. 5M). – foson

Powiązane problemy