How can I get a count of the total number of digits in a number?

C#MathNumbers

C# Problem Overview


How can I get a count of the total number of digits of a number in C#? For example, the number 887979789 has 9 digits.

C# Solutions


Solution 1 - C#

Without converting to a string you could try

Math.Floor(Math.Log10(n) + 1);

Solution 2 - C#

Try This:

myint.ToString().Length

Does that work ?

Solution 3 - C#

#The Solution#

Any of the following extension methods will do the job. All of them consider the minus sign as a digit, and work correctly for all possible input values. They also work for .NET Framework and for .NET Core. There are however relevant performance differences (discussed below), depending on your choice of Platform / Framework.

Int32 version:

public static class Int32Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this int n)
    {
        if (n >= 0)
        {
            if (n < 10) return 1;
            if (n < 100) return 2;
            if (n < 1000) return 3;
            if (n < 10000) return 4;
            if (n < 100000) return 5;
            if (n < 1000000) return 6;
            if (n < 10000000) return 7;
            if (n < 100000000) return 8;
            if (n < 1000000000) return 9;
            return 10;
        }
        else
        {
            if (n > -10) return 2;
            if (n > -100) return 3;
            if (n > -1000) return 4;
            if (n > -10000) return 5;
            if (n > -100000) return 6;
            if (n > -1000000) return 7;
            if (n > -10000000) return 8;
            if (n > -100000000) return 9;
            if (n > -1000000000) return 10;
            return 11;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this int n) =>
        n == 0 ? 1 : (n > 0 ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this int n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10) != 0) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this int n) =>
        n.ToString().Length;
}

Int64 version:

public static class Int64Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this long n)
    {
        if (n >= 0)
        {
            if (n < 10L) return 1;
            if (n < 100L) return 2;
            if (n < 1000L) return 3;
            if (n < 10000L) return 4;
            if (n < 100000L) return 5;
            if (n < 1000000L) return 6;
            if (n < 10000000L) return 7;
            if (n < 100000000L) return 8;
            if (n < 1000000000L) return 9;
            if (n < 10000000000L) return 10;
            if (n < 100000000000L) return 11;
            if (n < 1000000000000L) return 12;
            if (n < 10000000000000L) return 13;
            if (n < 100000000000000L) return 14;
            if (n < 1000000000000000L) return 15;
            if (n < 10000000000000000L) return 16;
            if (n < 100000000000000000L) return 17;
            if (n < 1000000000000000000L) return 18;
            return 19;
        }
        else
        {
            if (n > -10L) return 2;
            if (n > -100L) return 3;
            if (n > -1000L) return 4;
            if (n > -10000L) return 5;
            if (n > -100000L) return 6;
            if (n > -1000000L) return 7;
            if (n > -10000000L) return 8;
            if (n > -100000000L) return 9;
            if (n > -1000000000L) return 10;
            if (n > -10000000000L) return 11;
            if (n > -100000000000L) return 12;
            if (n > -1000000000000L) return 13;
            if (n > -10000000000000L) return 14;
            if (n > -100000000000000L) return 15;
            if (n > -1000000000000000L) return 16;
            if (n > -10000000000000000L) return 17;
            if (n > -100000000000000000L) return 18;
            if (n > -1000000000000000000L) return 19;
            return 20;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this long n) =>
        n == 0L ? 1 : (n > 0L ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this long n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10L) != 0L) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this long n) =>
        n.ToString().Length;
}

#Discussion#

This answer includes tests performed for both Int32 and Int64 types, using an array of 100.000.000 randomly sampled int / long numbers. The random dataset is pre-processed into an array before executing the tests.

Consistency tests among the 4 different methods were also executed, for MinValue, negative border cases, -1, 0, 1, positive border cases, MaxValue, and also for the whole random dataset. No consistency tests fail for the above provided methods, EXCEPT for the LOG10 method (this is discussed later).

The tests were executed on .NET Framework 4.7.2 and .NET Core 2.2; for x86 and x64 platforms, on a 64-bit Intel Processor machine, with Windows 10, and with VS2017 v.15.9.17. The following 4 cases have the same effect on performance results:

.NET Framework (x86)

  • Platform = x86

  • Platform = AnyCPU, Prefer 32-bit is checked in project settings

.NET Framework (x64)

  • Platform = x64

  • Platform = AnyCPU, Prefer 32-bit is unchecked in project settings

.NET Core (x86)

  • "C:\Program Files (x86)\dotnet\dotnet.exe" bin\Release\netcoreapp2.2\ConsoleApp.dll

  • "C:\Program Files (x86)\dotnet\dotnet.exe" bin\x86\Release\netcoreapp2.2\ConsoleApp.dll

.NET Core (x64)

  • "C:\Program Files\dotnet\dotnet.exe" bin\Release\netcoreapp2.2\ConsoleApp.dll

  • "C:\Program Files\dotnet\dotnet.exe" bin\x64\Release\netcoreapp2.2\ConsoleApp.dll

#Results#

The performance tests below produce a uniform distribution of values among the wide range of values an integer could assume. This means there is a much higher chance of testing values with a big count of digits. In real life scenarios, most values may be small, so the IF-CHAIN should perform even better. Furthermore, the processor will cache and optimize the IF-CHAIN decisions according to your dataset.

As @AlanSingfield pointed out in the comment section, the LOG10 method had to be fixed with a casting to double inside Math.Abs() for the case when the input value is int.MinValue or long.MinValue.

Regarding the early performance tests I've implemented before editing this question (it had to be edited a million times already), there was a specific case pointed out by @GyörgyKőszeg, in which the IF-CHAIN method performs slower than the LOG10 method.

This still happens, although the magnitude of the difference became much lower after the fix for the issue pointed out by @AlanSingfield. This fix (adding a cast to double) causes a computation error when the input value is exactly -999999999999999999: the LOG10 method returns 20 instead of 19. The LOG10 method also must have a if guard for the case when the input value is zero.

The LOG10 method is quite tricky to get working for all values, which means you should avoid it. If someone finds a way to make it work correctly for all the consistency tests below, please post a comment!

The WHILE method also got a recent refactored version which is faster, but it is still slow for Platform = x86 (I could not find the reason why, until now).

The STRING method is consistently slow: it greedily allocates too much memory for nothing. Interestingly, in .NET Core, string allocation seems to be much faster than in .NET Framework. Good to know.

The IF-CHAIN method should outperform all other methods in 99.99% of the cases; and, in my personal opinion, is your best choice (considering all the adjusts necessary to make the LOG10 method work correctly, and the bad performance of the other two methods).

Finally, the results are:

enter image description here

Since these results are hardware-dependent, I recommend anyway running the performance tests below on your own computer if you really need to be 100% sure in your specific case.

#Test Code#

Below is the code for the performance test, and the consistency test too. The same code is used for both .NET Framework and .NET Core.

using System;
using System.Diagnostics;

namespace NumberOfDigits
{
	// Performance Tests:
	class Program
	{
		private static void Main(string[] args)
		{
			Console.WriteLine("\r\n.NET Core");

			RunTests_Int32();
			RunTests_Int64();
		}

		// Int32 Performance Tests:
		private static void RunTests_Int32()
		{
			Console.WriteLine("\r\nInt32");

			const int size = 100000000;
			int[] samples = new int[size];
			Random random = new Random((int)DateTime.Now.Ticks);
			for (int i = 0; i < size; ++i)
				samples[i] = random.Next(int.MinValue, int.MaxValue);

			Stopwatch sw1 = new Stopwatch();
			sw1.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_IfChain();
			sw1.Stop();
			Console.WriteLine($"IfChain: {sw1.ElapsedMilliseconds} ms");

			Stopwatch sw2 = new Stopwatch();
			sw2.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_Log10();
			sw2.Stop();
			Console.WriteLine($"Log10: {sw2.ElapsedMilliseconds} ms");

			Stopwatch sw3 = new Stopwatch();
			sw3.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_While();
			sw3.Stop();
			Console.WriteLine($"While: {sw3.ElapsedMilliseconds} ms");

			Stopwatch sw4 = new Stopwatch();
			sw4.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_String();
			sw4.Stop();
			Console.WriteLine($"String: {sw4.ElapsedMilliseconds} ms");


			// Start of consistency tests:
			Console.WriteLine("Running consistency tests...");
			bool isConsistent = true;

			// Consistency test on random set:
			for (int i = 0; i < samples.Length; ++i)
			{
				int s = samples[i];
				int a = s.Digits_IfChain();
				int b = s.Digits_Log10();
				int c = s.Digits_While();
				int d = s.Digits_String();
				if (a != b || c != d || a != c)
				{
					Console.WriteLine($"Digits({s}): IfChain={a} Log10={b} While={c} String={d}");
					isConsistent = false;
					break;
				}
			}

			// Consistency test of special values:
            samples = new int[]
            {
                0,
                int.MinValue, -1000000000, -999999999, -100000000, -99999999, -10000000, -9999999, -1000000, -999999, -100000, -99999, -10000, -9999, -1000, -999, -100, -99, -10, -9, - 1,
                int.MaxValue, 1000000000, 999999999, 100000000, 99999999, 10000000, 9999999, 1000000, 999999, 100000, 99999, 10000, 9999, 1000, 999, 100, 99, 10, 9,  1,
            };
			for (int i = 0; i < samples.Length; ++i)
			{
				int s = samples[i];
				int a = s.Digits_IfChain();
				int b = s.Digits_Log10();
				int c = s.Digits_While();
				int d = s.Digits_String();
				if (a != b || c != d || a != c)
				{
					Console.WriteLine($"Digits({s}): IfChain={a} Log10={b} While={c} String={d}");
					isConsistent = false;
					break;
				}
			}

			// Consistency test result:
			if (isConsistent)
				Console.WriteLine("Consistency tests are OK");
		}

		// Int64 Performance Tests:
		private static void RunTests_Int64()
		{
			Console.WriteLine("\r\nInt64");

			const int size = 100000000;
			long[] samples = new long[size];
			Random random = new Random((int)DateTime.Now.Ticks);
			for (int i = 0; i < size; ++i)
				samples[i] = Math.Sign(random.Next(-1, 1)) * (long)(random.NextDouble() * long.MaxValue);

			Stopwatch sw1 = new Stopwatch();
			sw1.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_IfChain();
			sw1.Stop();
			Console.WriteLine($"IfChain: {sw1.ElapsedMilliseconds} ms");

			Stopwatch sw2 = new Stopwatch();
			sw2.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_Log10();
			sw2.Stop();
			Console.WriteLine($"Log10: {sw2.ElapsedMilliseconds} ms");

			Stopwatch sw3 = new Stopwatch();
			sw3.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_While();
			sw3.Stop();
			Console.WriteLine($"While: {sw3.ElapsedMilliseconds} ms");

			Stopwatch sw4 = new Stopwatch();
			sw4.Start();
			for (int i = 0; i < size; ++i) samples[i].Digits_String();
			sw4.Stop();
			Console.WriteLine($"String: {sw4.ElapsedMilliseconds} ms");

			// Start of consistency tests:
			Console.WriteLine("Running consistency tests...");
			bool isConsistent = true;

			// Consistency test on random set:
			for (int i = 0; i < samples.Length; ++i)
			{
				long s = samples[i];
				int a = s.Digits_IfChain();
				int b = s.Digits_Log10();
				int c = s.Digits_While();
				int d = s.Digits_String();
				if (a != b || c != d || a != c)
				{
					Console.WriteLine($"Digits({s}): IfChain={a} Log10={b} While={c} String={d}");
					isConsistent = false;
					break;
				}
			}

			// Consistency test of special values:
            samples = new long[] 
            {
                0,
                long.MinValue, -1000000000000000000, -999999999999999999, -100000000000000000, -99999999999999999, -10000000000000000, -9999999999999999, -1000000000000000, -999999999999999, -100000000000000, -99999999999999, -10000000000000, -9999999999999, -1000000000000, -999999999999, -100000000000, -99999999999, -10000000000, -9999999999, -1000000000, -999999999, -100000000, -99999999, -10000000, -9999999, -1000000, -999999, -100000, -99999, -10000, -9999, -1000, -999, -100, -99, -10, -9, - 1,
                long.MaxValue, 1000000000000000000, 999999999999999999, 100000000000000000, 99999999999999999, 10000000000000000, 9999999999999999, 1000000000000000, 999999999999999, 100000000000000, 99999999999999, 10000000000000, 9999999999999, 1000000000000, 999999999999, 100000000000, 99999999999, 10000000000, 9999999999, 1000000000, 999999999, 100000000, 99999999, 10000000, 9999999, 1000000, 999999, 100000, 99999, 10000, 9999, 1000, 999, 100, 99, 10, 9,  1,
            };
			for (int i = 0; i < samples.Length; ++i)
			{
				long s = samples[i];
				int a = s.Digits_IfChain();
				int b = s.Digits_Log10();
				int c = s.Digits_While();
				int d = s.Digits_String();
				if (a != b || c != d || a != c)
				{
					Console.WriteLine($"Digits({s}): IfChain={a} Log10={b} While={c} String={d}");
					isConsistent = false;
					break;
				}
			}

			// Consistency test result:
			if (isConsistent)
				Console.WriteLine("Consistency tests are OK");
		}
	}
}

Solution 4 - C#

Not directly C#, but the formula is: n = floor(log10(x)+1)

Solution 5 - C#

Answers already here work for unsigned integers, but I have not found good solutions for getting number of digits from decimals and doubles.

public static int Length(double number)
{
    number = Math.Abs(number);
    int length = 1;
    while ((number /= 10) >= 1)
        length++;
    return length;
}
//number of digits in 0 = 1,
//number of digits in 22.1 = 2,
//number of digits in -23 = 2

You may change input type from double to decimal if precision matters, but decimal has a limit too.

Solution 6 - C#

The answer of Steve is correct, but it doesn't work for integers less than 1.

Here an updated version that does work for negatives:

int digits = n == 0 ? 1 : Math.Floor(Math.Log10(Math.Abs(n)) + 1)

Solution 7 - C#

Using recursion (sometimes asked on interviews)

public int CountDigits(int number)
{
    // In case of negative numbers
    number = Math.Abs(number);

    if (number >= 10)
        return CountDigits(number / 10) + 1;
    return 1;
 }

Solution 8 - C#

static void Main(string[] args)
{
    long blah = 20948230498204;
    Console.WriteLine(blah.ToString().Length);
}

Solution 9 - C#

Here's an implementation using a binary search. Looks to be the fastest so far on int32.

Int64 implementation is left as an exercise for the reader(!)

I tried using Array.BinarySearch rather than hard-coding the tree, but that was about half the speed.

EDIT: A lookup table is much faster than the binary search, at the expense of using more memory. Realistically I'd probably use the binary search one in production, the lookup table is a lot of complexity for a speed gain that's likely to be overshadowed by other parts of the software.

Lookup-Table: 439 ms
Binary-Search: 1069 ms
If-Chain: 1409 ms
Log10: 1145 ms
While: 1768 ms
String: 5153 ms

Lookup table version:

static byte[] _0000llll = new byte[0x10000];
static byte[] _FFFFllll = new byte[0x10001];
static sbyte[] _hhhhXXXXdigits = new sbyte[0x10000];

// Special cases where the high DWORD is not enough information to find out how
// many digits.
static ushort[] _lowordSplits = new ushort[12];
static sbyte[] _lowordSplitDigitsLT = new sbyte[12];
static sbyte[] _lowordSplitDigitsGE = new sbyte[12];

static Int32Extensions()
{
    // Simple lookup tables for number of digits where value is 
    //    0000xxxx (0 .. 65535)
    // or FFFFxxxx (-1 .. -65536)
    precomputePositiveLo16();
    precomputeNegativeLo16();

    // Hiword is a little more complex
    precomputeHiwordDigits();
}

private static void precomputeHiwordDigits()
{
    int b = 0;

    for(int hhhh = 0; hhhh <= 0xFFFF; hhhh++)
    {
        // For hiword hhhh, calculate integer value for loword of 0000 and FFFF.
        int hhhh0000 = (unchecked(hhhh * 0x10000));  // wrap around on negatives
        int hhhhFFFF = hhhh0000 + 0xFFFF;

        // How many decimal digits for each?
        int digits0000 = hhhh0000.Digits_IfChain();
        int digitsFFFF = hhhhFFFF.Digits_IfChain();

        // If same number of decimal digits, we know that when we see that hiword
        // we don't have to look at the loword to know the right answer.
        if(digits0000 == digitsFFFF)
        {
            _hhhhXXXXdigits[hhhh] = (sbyte)digits0000;
        }
        else
        {
            bool negative = hhhh >= 0x8000;

            // Calculate 10, 100, 1000, 10000 etc
            int tenToThePower = (int)Math.Pow(10, (negative ? digits0000 : digitsFFFF) - 1);

            // Calculate the loword of the 10^n value.
            ushort lowordSplit = unchecked((ushort)tenToThePower);
            if(negative)
                lowordSplit = unchecked((ushort)(2 + (ushort)~lowordSplit));

            // Store the split point and digits into these arrays
            _lowordSplits[b] = lowordSplit;
            _lowordSplitDigitsLT[b] = (sbyte)digits0000;
            _lowordSplitDigitsGE[b] = (sbyte)digitsFFFF;

            // Store the minus of the array index into the digits lookup. We look for
            // minus values and use these to trigger using the split points logic.
            _hhhhXXXXdigits[hhhh] = (sbyte)(-b);
            b++;
        }
    }
}

private static void precomputePositiveLo16()
{
    for(int i = 0; i <= 9; i++)
        _0000llll[i] = 1;

    for(int i = 10; i <= 99; i++)
        _0000llll[i] = 2;

    for(int i = 100; i <= 999; i++)
        _0000llll[i] = 3;

    for(int i = 1000; i <= 9999; i++)
        _0000llll[i] = 4;

    for(int i = 10000; i <= 65535; i++)
        _0000llll[i] = 5;
}

private static void precomputeNegativeLo16()
{
    for(int i = 0; i <= 9; i++)
        _FFFFllll[65536 - i] = 1;

    for(int i = 10; i <= 99; i++)
        _FFFFllll[65536 - i] = 2;

    for(int i = 100; i <= 999; i++)
        _FFFFllll[65536 - i] = 3;

    for(int i = 1000; i <= 9999; i++)
        _FFFFllll[65536 - i] = 4;

    for(int i = 10000; i <= 65535; i++)
        _FFFFllll[65536 - i] = 5;
}



public static int Digits_LookupTable(this int n)
{
    // Split input into low word and high word.
    ushort l = unchecked((ushort)n);
    ushort h = unchecked((ushort)(n >> 16));

    // If the hiword is 0000 or FFFF we have precomputed tables for these.
    if(h == 0x0000)
    {
        return _0000llll[l];
    }
    else if(h == 0xFFFF)
    {
        return _FFFFllll[l];
    }

    // In most cases the hiword will tell us the number of decimal digits.
    sbyte digits = _hhhhXXXXdigits[h];

    // We put a positive number in this lookup table when
    // hhhh0000 .. hhhhFFFF all have the same number of decimal digits.
    if(digits > 0)
        return digits;

    // Where the answer is different for hhhh0000 to hhhhFFFF, we need to
    // look up in a separate array to tell us at what loword the change occurs.
    var splitIndex = (sbyte)(-digits);

    ushort lowordSplit = _lowordSplits[splitIndex];

    // Pick the correct answer from the relevant array, depending whether
    // our loword is lower than the split point or greater/equal. Note that for
    // negative numbers, the loword is LOWER for MORE decimal digits.
    if(l < lowordSplit)
        return _lowordSplitDigitsLT[splitIndex];
    else
        return _lowordSplitDigitsGE[splitIndex];
}

Binary search version

        public static int Digits_BinarySearch(this int n)
        {
            if(n >= 0)
            {
                if(n <= 9999) // 0 .. 9999
                {
                    if(n <= 99) // 0 .. 99
                    {
                        return (n <= 9) ? 1 : 2;
                    }
                    else // 100 .. 9999
                    {
                        return (n <= 999) ? 3 : 4;
                    }
                }
                else // 10000 .. int.MaxValue
                {
                    if(n <= 9_999_999) // 10000 .. 9,999,999
                    {
                        if(n <= 99_999)
                            return 5;
                        else if(n <= 999_999)
                            return 6;
                        else
                            return 7;
                    }
                    else // 10,000,000 .. int.MaxValue
                    {
                        if(n <= 99_999_999)
                            return 8;
                        else if(n <= 999_999_999)
                            return 9;
                        else
                            return 10;
                    }
                }
            }
            else
            {
                if(n >= -9999) // -9999 .. -1
                {
                    if(n >= -99) // -99 .. -1
                    {
                        return (n >= -9) ? 1 : 2;
                    }
                    else // -9999 .. -100
                    {
                        return (n >= -999) ? 3 : 4;
                    }
                }
                else // int.MinValue .. -10000
                {
                    if(n >= -9_999_999) // -9,999,999 .. -10000
                    {
                        if(n >= -99_999)
                            return 5;
                        else if(n >= -999_999)
                            return 6;
                        else
                            return 7;
                    }
                    else // int.MinValue .. -10,000,000 
                    {
                        if(n >= -99_999_999)
                            return 8;
                        else if(n >= -999_999_999)
                            return 9;
                        else
                            return 10;
                    }
                }
            }
        }

        Stopwatch sw0 = new Stopwatch();
        sw0.Start();
        for(int i = 0; i < size; ++i) samples[i].Digits_BinarySearch();
        sw0.Stop();
        Console.WriteLine($"Binary-Search: {sw0.ElapsedMilliseconds} ms");

Solution 10 - C#

dividing a number by 10 will give you the left most digit then doing a mod 10 on the number gives the number without the first digit and repeat that till you have all the digits

Solution 11 - C#

int i = 855865264;
int NumLen = i.ToString().Length;

Solution 12 - C#

Total digits of integer:

      double input = Convert.ToDouble(Console.ReadLine());
      double b = Math.Floor(Math.Log10(input) + 1);          
      int c = Convert.ToInt32(b);

Solution 13 - C#

Not able to comment, but this is in relation to sɐunıɔןɐqɐp's excellent comment.
This function works with doubles. I also believe there was an error with the negative comparisons.

    /// <summary>
    /// counts the digits of the integral part of a number. <br></br>
    ///  4 -> 1; 4.3 -> 1; -4 -> 1; -0.4 -> 0, 1e53 -> 53
    /// </summary>
    /// <param name="n"></param>
    /// <returns>number 1+</returns>
    public static int IntegralDigitLength( double n )
    {
        //this if-chain is allegedly the best way
        //https://stackoverflow.com/questions/4483886/how-can-i-get-a-count-of-the-total-number-of-digits-in-a-number
        if(n< 1 && n > -1 )
        {
            return 0;
        }
        if( n >= 0 )
        {
            if( n < 10L ) return 1;
            if( n < 100L ) return 2;
            if( n < 1000L ) return 3;
            if( n < 10000L ) return 4;
            if( n < 100000L ) return 5;
            if( n < 1000000L ) return 6;
            if( n < 10000000L ) return 7;
            if( n < 100000000L ) return 8;
            if( n < 1000000000L ) return 9;
            if( n < 10000000000L ) return 10;
            if( n < 100000000000L ) return 11;
            if( n < 1000000000000L ) return 12;
            if( n < 10000000000000L ) return 13;
            if( n < 100000000000000L ) return 14;
            if( n < 1000000000000000L ) return 15;
            if( n < 10000000000000000L ) return 16;
            if( n < 100000000000000000L ) return 17;
            if( n < 1000000000000000000L ) return 18;

            n = Math.Floor( n );
            var numOfDigits = 19;
            while( true )
            {

                double comparison = Math.Pow( 10, numOfDigits );
                if( n <= comparison )
                {
                    return numOfDigits;
                }
                numOfDigits++;
            }
        }
        else
        {
            if( n > -10L ) return 1;
            if( n > -100L ) return 2;
            if( n > -1000L ) return 3;
            if( n > -10000L ) return 4;
            if( n > -100000L ) return 5;
            if( n > -1000000L ) return 6;
            if( n > -10000000L ) return 7;
            if( n > -100000000L ) return 8;
            if( n > -1000000000L ) return 9;
            if( n > -10000000000L ) return 10;
            if( n > -100000000000L ) return 11;
            if( n > -1000000000000L ) return 12;
            if( n > -10000000000000L ) return 13;
            if( n > -100000000000000L ) return 14;
            if( n > -1000000000000000L ) return 15;
            if( n > -10000000000000000L ) return 16;
            if( n > -100000000000000000L ) return 17;
            if( n > -1000000000000000000L ) return 18;
            n = Math.Floor( n );
            var numOfDigits = 19;
            while( true )
            {
                if( n <= Math.Pow( -10, numOfDigits ) )
                {
                    return numOfDigits;
                }
                numOfDigits++;
            }
        }
    }

It passes the following unit tests:

    [Test]
public void IntegralDigitLength()
{

    Assert.AreEqual( 1, Logic.IntegralDigitLength( 1 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( 2 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( -3 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( -3.4 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( 3.4 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( 9.9 ) );
    Assert.AreEqual( 2, Logic.IntegralDigitLength( 10 ) );
    Assert.AreEqual( 2, Logic.IntegralDigitLength( 19 ) );
    Assert.AreEqual( 2, Logic.IntegralDigitLength( 19.9 ) );
    Assert.AreEqual( 2, Logic.IntegralDigitLength( -19.9 ) );
    Assert.AreEqual( 5, Logic.IntegralDigitLength( 12345 ) );
    Assert.AreEqual( 5, Logic.IntegralDigitLength( 92345 ) );
    Assert.AreEqual( 4, Logic.IntegralDigitLength( 02345 ) );
    Assert.AreEqual( 1, Logic.IntegralDigitLength( 00005 ) );
    Assert.AreEqual( 8, Logic.IntegralDigitLength( 47616294 ) );
    Assert.AreEqual( 8, Logic.IntegralDigitLength( -47616294 ) );
    Assert.AreEqual( 25, Logic.IntegralDigitLength( 1111111111111111111111111f ) );
    Assert.AreEqual( 25, Logic.IntegralDigitLength( 4444444444444444444444444f ) );
    Assert.AreEqual( 25, Logic.IntegralDigitLength( 9999999999999999999999999f ) );
    Assert.AreEqual( 25, Logic.IntegralDigitLength( 1e25 ) );
    Assert.AreEqual( 305, Logic.IntegralDigitLength( 1e305 ) );
    Assert.AreEqual( 0, Logic.IntegralDigitLength( 1e-3 ) );
}

NB: the last one returns zero, I want it to return 0 for values less than one but greater than -1.

Solution 14 - C#

It depends what exactly you want to do with the digits. You can iterate through the digits starting from the last to the first one like this:

int tmp = number;
int lastDigit = 0;
do
{
    lastDigit = tmp / 10;
    doSomethingWithDigit(lastDigit);
    tmp %= 10;
} while (tmp != 0);

Solution 15 - C#

Create a method that returns all digits, and another that counts them:

public static int GetNumberOfDigits(this long value)
{
    return value.GetDigits().Count();
}

public static IEnumerable<int> GetDigits(this long value)
{
    do
    {
        yield return (int)(value % 10);
        value /= 10;
    } while (value != 0);
}

This felt like the more intuitive approach to me when tackling this problem. I tried the Log10 method first due to its apparent simplicity, but it has an insane amount of corner cases and precision problems.

I also found the if-chain proposed in the other answer to a bit ugly to look at.

I know this is not the most efficient method, but it gives you the other extension to return the digits as well for other uses (you can just mark it private if you don't need to use it outside the class).

Keep in mind that it does not consider the negative sign as a digit.

Solution 16 - C#

convert into string and then you can count tatal no of digit by .length method. Like:

String numberString = "855865264".toString();
int NumLen = numberString .Length;

Solution 17 - C#

If its only for validating you could do: 887979789 > 99999999

Solution 18 - C#

Assuming your question was referring to an int, the following works for negative/positive and zero as well:

Math.Floor((decimal) Math.Abs(n)).ToString().Length

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArashView Question on Stackoverflow
Solution 1 - C#SteveView Answer on Stackoverflow
Solution 2 - C#AndiihView Answer on Stackoverflow
Solution 3 - C#sɐunıɔןɐqɐpView Answer on Stackoverflow
Solution 4 - C#ysapView Answer on Stackoverflow
Solution 5 - C#nawfalView Answer on Stackoverflow
Solution 6 - C#Patrick HofmanView Answer on Stackoverflow
Solution 7 - C#user2673195View Answer on Stackoverflow
Solution 8 - C#weloyttyView Answer on Stackoverflow
Solution 9 - C#Alan SingfieldView Answer on Stackoverflow
Solution 10 - C#romejoeView Answer on Stackoverflow
Solution 11 - C#Javed AkramView Answer on Stackoverflow
Solution 12 - C#RakibulView Answer on Stackoverflow
Solution 13 - C#sheepdeetsView Answer on Stackoverflow
Solution 14 - C#Mihran HovsepyanView Answer on Stackoverflow
Solution 15 - C#julealgonView Answer on Stackoverflow
Solution 16 - C#user5585864View Answer on Stackoverflow
Solution 17 - C#Johan van der SlikkeView Answer on Stackoverflow
Solution 18 - C#Petru ZahariaView Answer on Stackoverflow