Я просто наткнулся на этот старый вопрос и был склонен предложить другое предложение, поскольку ни один из других ответов пока не возвращает правильный результат для всех возможных входных значений, и он все еще сделать быстрее:
public static int GetFirstDigit( int i )
{
if( i < 0 && ( i = -i ) < 0 ) return 2;
return ( i < 100 ) ? ( i < 1 ) ? 0 : ( i < 10 )
? i : i / 10 : ( i < 1000000 ) ? ( i < 10000 )
? ( i < 1000 ) ? i / 100 : i / 1000 : ( i < 100000 )
? i / 10000 : i / 100000 : ( i < 100000000 )
? ( i < 10000000 ) ? i / 1000000 : i / 10000000
: ( i < 1000000000 ) ? i / 100000000 : i / 1000000000;
}
Это работает для всех целочисленных значений со знаком, включая -2147483648
, которое является наименьшим целым числом со знаком и не имеет положительного аналога. Math.Abs( -2147483648 )
запускает System.OverflowException
, а - -2147483648
вычисляет до -2147483648
.
Реализация может рассматриваться как комбинация преимуществ двух самых быстрых реализаций на данный момент. Он использует бинарный поиск и избегает лишних делений. Быстрый тест с индексом цикла с 100 000 000 итераций показывает, что он в два раза быстрее, чем самая быстрая в настоящее время реализация.
Завершается после 2,829,581 тиков.
Для сравнения я также измерил исправленный вариант самой быстрой на данный момент реализации, который занял 5 664 627 тиков.
public static int GetFirstDigitX( int i )
{
if( i < 0 && ( i = -i ) < 0 ) return 2;
if( i >= 100000000 ) i /= 100000000;
if( i >= 10000 ) i /= 10000;
if( i >= 100 ) i /= 100;
if( i >= 10 ) i /= 10;
return i;
}
Принятый ответ с той же коррекцией, необходимой 16 561 929 отметок для этого теста на моем компьютере.
public static int GetFirstDigitY( int i )
{
if( i < 0 && ( i = -i ) < 0 ) return 2;
while( i >= 10 )
i /= 10;
return i;
}
Простые функции, подобные этим, могут быть легко проверены на корректность, поскольку итерирование всех возможных целочисленных значений занимает не более нескольких секунд на текущем оборудовании. Это означает, что менее важно реализовывать их исключительно читабельным образом, поскольку в будущем просто не будет необходимости исправлять в них ошибку.