Me encontré con esta vieja pregunta y me sentí inclinado a proponer otra sugerencia, ya que ninguna de las otras respuestas hasta ahora devuelve el resultado correcto para todos los valores de entrada posibles y aún se puede hacer más rápido:
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;
}
Esto funciona para todos los valores enteros con signo inclusive, -2147483648que es el entero con signo más pequeño y no tiene una contraparte positiva. Math.Abs( -2147483648 )disparadores una System.OverflowExceptiony - -2147483648computa a-2147483648 .
La implementación puede verse como una combinación de las ventajas de las dos implementaciones más rápidas hasta ahora. Utiliza una búsqueda binaria y evita divisiones superfluas. Un punto de referencia rápido con el índice de un bucle con 100.000.000 de iteraciones muestra que es dos veces más rápido que la implementación más rápida actualmente.
Termina después de 2.829.581 tics.
A modo de comparación, también medí una variante corregida de la implementación más rápida actualmente que tomó 5,664,627 ticks.
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;
}
La respuesta aceptada con la misma corrección necesitó 16,561,929 ticks para esta prueba en mi computadora.
public static int GetFirstDigitY( int i )
{
if( i < 0 && ( i = -i ) < 0 ) return 2;
while( i >= 10 )
i /= 10;
return i;
}
Se puede probar fácilmente que funciones simples como estas son correctas, ya que la iteración de todos los valores enteros posibles no toma mucho más que unos pocos segundos en el hardware actual. Esto significa que es menos importante implementarlos de una manera excepcionalmente legible, ya que simplemente nunca será necesario corregir un error dentro de ellos más adelante.