7

I would like a c# function with this signature:

int GetSignificantNumberOfDecimalPlaces(decimal d)

It should behave as follows when called:

    GetSignificantNumberOfDecimalPlaces(2.12300m); // returns 3
    GetSignificantNumberOfDecimalPlaces(2.123m);   // returns 3
    GetSignificantNumberOfDecimalPlaces(2.103450m);  // returns 5
    GetSignificantNumberOfDecimalPlaces(2.0m); // returns 0
    GetSignificantNumberOfDecimalPlaces(2.00m); // returns 0
    GetSignificantNumberOfDecimalPlaces(2m); // returns 0

i.e. for a given decimal, i want the number of significant decimal places to the right of the decimal point. So trailing zeros can be ignored. My fallback is to turn the decimal into a string, trim trailing zeros, and get the length this way. But is there a better way ?

NOTE: I may be using the word "significant" incorrectly here. The required return values in the example should hopefully explain what i'm after.

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
Moe Sisko
  • 11,665
  • 8
  • 50
  • 80

4 Answers4

6

Some very good answers here Parse decimal and filter extra 0 on the right?

decimal d = -123.456700m;

decimal n = d / 1.000000000000000000000000000000m;  // -123.4567m

int[] bits = decimal.GetBits(n);

int count = bits[3] >> 16 & 255; // 4        or byte count = (byte)(bits[3] >> 16);
Community
  • 1
  • 1
Slai
  • 22,144
  • 5
  • 45
  • 53
3

I can help you to do the same with a few string operations, This may be a workaround solution for your problem, anyway consider this suggestion, and hope that it would help you

static int GetSignificantNumberOfDecimalPlaces(decimal d)
{
    string inputStr = d.ToString(CultureInfo.InvariantCulture);
    int decimalIndex = inputStr.IndexOf(".") + 1;
    if (decimalIndex == 0)
    {
        return 0;
    }
    return inputStr.Substring(decimalIndex).TrimEnd(new[] { '0' }).Length;    
}

Working Example with all the specified inputs

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
0

I think this was answered before: stackoverflow.com/a/13493771/4779385

decimal argument = 123.456m;
int count = BitConverter.GetBytes(decimal.GetBits(argument)[3])[2];
HackSlash
  • 4,944
  • 2
  • 18
  • 44
mindOfAi
  • 4,412
  • 2
  • 16
  • 27
  • there's a difference between 123.456m and 123.4560m. i.e. if the decimal i pass in has trailing zeros, the routine should ignore them. Your code works for calling with 123.456m, but not for 123.4560m, for example. – Moe Sisko Feb 16 '17 at 03:53
-1

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace NumberofOnes

{

public class Program

{

    static void Main(string[] args)

    {

        Console.WriteLine("enter numbers");

        decimal argument = Convert.ToDecimal(Console.ReadLine());

        double count = Convert.ToDouble(decimal.Remainder(argument, 1));

        string number = count.ToString();

        int decimalCount = 0;

        if (number.Length > 1)

        {

            decimalCount = number.Length - 2;

        }

        Console.WriteLine("decimal:" + decimalCount);

        Console.ReadKey();

    }

}

}

hope this work!!