C# Check if a decimal has more than 3 decimal places?

You could compare the value of the number rounded to 3 decimal places with the original value.

if (Decimal.Round(valueDecimal, 3) != valueDecimal)
{
   //Too many decimals
}

This works for 3 decimal places, and it can be adapted for a generic solution:

static bool LessThan3DecimalPlaces(decimal dec)
{
    decimal value = dec * 1000;
    return value == Math.Floor(value);
}
static void Test()
{
    Console.WriteLine(LessThan3DecimalPlaces(1m * 0.00025m));
    Console.WriteLine(LessThan3DecimalPlaces(4000m * 0.00025m));
}

For a real generic solution, you'll need to "deconstruct" the decimal value in its parts - take a look at Decimal.GetBits for more information.

Update: this is a simple implementation of a generic solution which works for all decimals whose integer part is less than long.MaxValue (you'd need something like a "big integer" for a trully generic function).

static decimal CountDecimalPlaces(decimal dec)
{
    Console.Write("{0}: ", dec);
    int[] bits = Decimal.GetBits(dec);
    ulong lowInt = (uint)bits[0];
    ulong midInt = (uint)bits[1];
    int exponent = (bits[3] & 0x00FF0000) >> 16;
    int result = exponent;
    ulong lowDecimal = lowInt | (midInt << 32);
    while (result > 0 && (lowDecimal % 10) == 0)
    {
        result--;
        lowDecimal /= 10;
    }

    return result;
}

static void Foo()
{
    Console.WriteLine(CountDecimalPlaces(1.6m));
    Console.WriteLine(CountDecimalPlaces(1.600m));
    Console.WriteLine(CountDecimalPlaces(decimal.MaxValue));
    Console.WriteLine(CountDecimalPlaces(1m * 0.00025m));
    Console.WriteLine(CountDecimalPlaces(4000m * 0.00025m));
}

This is a very simple one line code to get count of decimals in a Decimal:

decimal myDecimal = 1.000000021300010000001m;
byte decimals = (byte)((Decimal.GetBits(myDecimal)[3] >> 16) & 0x7F);

Tags:

C#

Decimal