Encuentre el número de decimales en el valor decimal independientemente de la cultura
Me pregunto si existe una forma concisa y precisa de extraer el número de decimales en un valor decimal (como un int) que sea seguro de usar en diferentes informaciones culturales.
Por ejemplo:
19.0 debería devolver 1,
27.5999 debería devolver 4,
19.12 debería devolver 2,
etc.
Escribí una consulta que dividía una cadena en un punto para encontrar lugares decimales:
int priceDecimalPlaces = price.ToString().Split('.').Count() > 1
? price.ToString().Split('.').ToList().ElementAt(1).Length
: 0;
Pero se me ocurre que esto sólo funcionará en regiones que utilicen el '.' como separador decimal y, por lo tanto, es muy frágil en diferentes sistemas.
Utilicé la forma de Joe para resolver este problema :)
decimal argument = 123.456m;
int count = BitConverter.GetBytes(decimal.GetBits(argument)[3])[2];
Dado que ninguna de las respuestas proporcionadas fue lo suficientemente buena para convertir el número mágico "-0.01f" a decimal... es decir: GetDecimal((decimal)-0.01f);
solo puedo asumir que un colosal virus mental atacó a todos hace 3 años :)
Esto es lo que parece ser un virus que funciona implementación de este malvado y monstruoso problema, el muy complicado problema de contar los lugares decimales después del punto: sin cadenas, sin culturas, sin necesidad de contar los bits y sin necesidad de leer foros de matemáticas... simplemente matemáticas simples de tercer grado.
public static class MathDecimals
{
public static int GetDecimalPlaces(decimal n)
{
n = Math.Abs(n); //make sure it is positive.
n -= (int)n; //remove the integer part of the number.
var decimalPlaces = 0;
while (n > 0)
{
decimalPlaces++;
n *= 10;
n -= (int)n;
}
return decimalPlaces;
}
}
private static void Main(string[] args)
{
Console.WriteLine(1/3m); //this is 0.3333333333333333333333333333
Console.WriteLine(1/3f); //this is 0.3333333
Console.WriteLine(MathDecimals.GetDecimalPlaces(0.0m)); //0
Console.WriteLine(MathDecimals.GetDecimalPlaces(1/3m)); //28
Console.WriteLine(MathDecimals.GetDecimalPlaces((decimal)(1 / 3f))); //7
Console.WriteLine(MathDecimals.GetDecimalPlaces(-1.123m)); //3
Console.WriteLine(MathDecimals.GetDecimalPlaces(43.12345m)); //5
Console.WriteLine(MathDecimals.GetDecimalPlaces(0)); //0
Console.WriteLine(MathDecimals.GetDecimalPlaces(0.01m)); //2
Console.WriteLine(MathDecimals.GetDecimalPlaces(-0.001m)); //3
Console.WriteLine(MathDecimals.GetDecimalPlaces((decimal)-0.00000001f)); //8
Console.WriteLine(MathDecimals.GetDecimalPlaces((decimal)0.0001234f)); //7
Console.WriteLine(MathDecimals.GetDecimalPlaces((decimal)0.01f)); //2
Console.WriteLine(MathDecimals.GetDecimalPlaces((decimal)-0.01f)); //2
}