How can you get the first digit in an int (C#)?

Solution 1:

Benchmarks

Firstly, you must decide on what you mean by "best" solution, of course that takes into account the efficiency of the algorithm, its readability/maintainability, and the likelihood of bugs creeping up in the future. Careful unit tests can generally avoid those problems, however.

I ran each of these examples 10 million times, and the results value is the number of ElapsedTicks that have passed.

Without further ado, from slowest to quickest, the algorithms are:

Converting to a string, take first character

int firstDigit = (int)(Value.ToString()[0]) - 48;

Results:

12,552,893 ticks

Using a logarithm

int firstDigit = (int)(Value / Math.Pow(10, (int)Math.Floor(Math.Log10(Value))));

Results:

9,165,089 ticks

Looping

while (number >= 10)
    number /= 10;

Results:

6,001,570 ticks

Conditionals

int firstdigit;
if (Value < 10)
     firstdigit = Value;
else if (Value < 100)
     firstdigit = Value / 10;
else if (Value < 1000)
     firstdigit = Value / 100;
else if (Value < 10000)
     firstdigit = Value / 1000;
else if (Value < 100000)
     firstdigit = Value / 10000;
else if (Value < 1000000)
     firstdigit = Value / 100000;
else if (Value < 10000000)
     firstdigit = Value / 1000000;
else if (Value < 100000000)
     firstdigit = Value / 10000000;
else if (Value < 1000000000)
     firstdigit = Value / 100000000;
else
     firstdigit = Value / 1000000000;

Results:

1,421,659 ticks

Unrolled & optimized loop

if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;

Results:

1,399,788 ticks

Note:

each test calls Random.Next() to get the next int

Solution 2:

Here's how

int i = Math.Abs(386792);
while(i >= 10)
    i /= 10;

and i will contain what you need

Solution 3:

Try this

public int GetFirstDigit(int number) {
  if ( number < 10 ) {
    return number;
  }
  return GetFirstDigit ( (number - (number % 10)) / 10);
}

EDIT

Several people have requested the loop version

public static int GetFirstDigitLoop(int number)
{
    while (number >= 10)
    {
        number = (number - (number % 10)) / 10;
    }
    return number;
}

Solution 4:

The best I can come up with is:

int numberOfDigits = Convert.ToInt32(Math.Floor( Math.Log10( value ) ) );

int firstDigit = value / Math.Pow( 10, numberOfDigits );

Solution 5:

variation on Anton's answer:

 // cut down the number of divisions (assuming i is positive & 32 bits)
if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;