2012-06-14 15 views
13

Me gustaría convertir un decimal a una cadena, con comas como separadores de miles, y conservar la misma precisión con la que se creó el decimal. (Tendrá 2-5 dígitos significativos)Formato decimal con comas, preservar los ceros finales

 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 

¿No hay construida en forma de hacerlo sin necesidad de analizar la cadena de forma manual? Si no hay una cadena de formato único, ¿cuál es la forma más fácil de hacer esto?

+0

Decidí ver cómo se realiza el formateo. Lamentablemente, el levantamiento de pesas no es código administrado (nada sorprendente) al mirar la [Cadena estándar de formato numérico] (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#GFormatString) parece que solo '" G "' (el valor predeterminado) conserva el espacio en blanco. – Guvante

Respuesta

12

De acuerdo con documentation, un número decimal conserva los ceros finales. Puede visualizarlos si utiliza el especificador "G" o ningún especificador en absoluto. Se pierden cuando usa uno de los especificadores que incluye un separador de mil.

Si desea especificar el número de ceros en la conversión a cadena, puede hacerlo mediante la adición de a precision specifier (0 a 99 dígitos) después de que el carácter de formato, como este:

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

el resultado será ser

1,234.4500 

ACTUALIZACIÓN: Usted puede obtener el número de dígitos decimales utilizando el método Decimal.GetBits que devuelve la representación binaria del número. El número de decimales se almacena en los bits 16-23 (tercer byte) del cuarto elemento.

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.

Primeros una representación de cadena utilizando todos los dígitos se puede hacer así:

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

que producirá

1,234.45000 
+0

Usted es parcialmente incorrecto. Aunque el depurador mostrará que el valor decimal es igual a 1234.45, los 0 finales se conservan. Pruebe el siguiente código, por ejemplo: 'decimal d = 1234.4500M;' 'Console.WriteLine (d); // salidas 1234.4500'. –

+1

Su respuesta solo cubre el ejemplo donde el número tiene exactamente 4 decimales. Creo que está tratando de preservar el número original de decimales (2-5). –

+1

El formato se especifica como un número dividido por una potencia de 10. Por esta razón, puede almacenar 12345/100 o 1234500/10000 distintivamente. – Guvante

1

Dado que planea tener un número variable de decimales (2-5), no creo que pueda llevarlo a cabo mediante un formato de cadena.

Esta solución no es necesariamente bonita, pero hace el trabajo. Tenga en cuenta que asignará varias cadenas en el proceso (creo que 5), por lo que puede no funcionar bien en el uso a gran escala. Conservará la cantidad de decimales y obtendrá grupos separados por comas en la parte anterior al decimal.

public static string FormatDecimal(decimal d) 
{ 
    return d.ToString("N0") + // Format portion before decimal 
      "." + 
      d.ToString().Split('.')[1]; // Retain number of decimal places 
} 
+0

Puede extraer el número de dígitos de la representación binaria del decimal y construir una cadena de formato con el número correcto de dígitos –

+0

También está utilizando separadores específicos de cultura, lo que significa que su código se romperá si se usa en una cultura que usa ' , 'para decimales, como Francia, Alemania, España, Italia, Grecia, Sudáfrica –

+0

Me gusta - es bastante fácil de entender el código de un vistazo. Aunque podría obtener un índice fuera de límites si el valor no tiene un componente decimal (como 5M) – foson

Cuestiones relacionadas