Ich bin gerade auf diese alte Frage gestoßen und war geneigt, einen anderen Vorschlag vorzuschlagen, da keine der anderen Antworten bisher das richtige Ergebnis für alle möglichen Eingabewerte liefert und es immer noch schneller gemacht werden kann:
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;
}
Dies funktioniert für alle vorzeichenbehafteten Ganzzahlwerte einschließlich, wobei -2147483648dies die kleinste vorzeichenbehaftete Ganzzahl ist und kein positives Gegenstück hat. Math.Abs( -2147483648 )löst a aus System.OverflowExceptionund - -2147483648berechnet zu-2147483648 .
Die Implementierung kann als eine Kombination der Vorteile der beiden bisher schnellsten Implementierungen angesehen werden. Es verwendet eine binäre Suche und vermeidet überflüssige Unterteilungen. Ein schneller Benchmark mit dem Index einer Schleife mit 100.000.000 Iterationen zeigt, dass sie doppelt so schnell ist wie die derzeit schnellste Implementierung.
Es endet nach 2.829.581 Zecken.
Zum Vergleich habe ich auch eine korrigierte Variante der derzeit schnellsten Implementierung gemessen, die 5.664.627 Ticks benötigte.
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;
}
Die akzeptierte Antwort mit der gleichen Korrektur benötigte 16.561.929 Ticks für diesen Test auf meinem Computer.
public static int GetFirstDigitY( int i )
{
if( i < 0 && ( i = -i ) < 0 ) return 2;
while( i >= 10 )
i /= 10;
return i;
}
Einfache Funktionen wie diese können leicht auf ihre Richtigkeit überprüft werden, da das Iterieren aller möglichen ganzzahligen Werte auf der aktuellen Hardware nicht viel länger als einige Sekunden dauert. Dies bedeutet, dass es weniger wichtig ist, sie auf außergewöhnlich lesbare Weise zu implementieren, da es später einfach nie notwendig sein wird, einen Fehler in ihnen zu beheben.