Find number of decimal places in decimal value regardless of culture
I'm wondering if there is a concise and accurate way to pull out the number of decimal places in a decimal value (as an int) that will be safe to use across different culture info?
For example:
19.0 should return 1,
27.5999 should return 4,
19.12 should return 2,
etc.
I wrote a query that did a string split on a period to find decimal places:
int priceDecimalPlaces = price.ToString().Split('.').Count() > 1
? price.ToString().Split('.').ToList().ElementAt(1).Length
: 0;
But it occurs to me that this will only work in regions that use the '.' as a decimal separator and is therefore very brittle across different systems.
Solution 1:
I used Joe's way to solve this issue :)
decimal argument = 123.456m;
int count = BitConverter.GetBytes(decimal.GetBits(argument)[3])[2];
Solution 2:
Since none of the answers supplied were good enough for the magic number "-0.01f" converted to decimal.. i.e: GetDecimal((decimal)-0.01f);
I can only assume a colossal mind-fart virus attacked everyone 3 years ago :)
Here is what seems to be a working implementation to this evil and monstrous problem, the very complicated problem of counting the decimal places after the point - no strings, no cultures, no need to count the bits and no need to read math forums.. just simple 3rd grade math.
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
}