Любое из этих расширений выполнит свою работу:
public static class Int32Extensions
{
// THE MATHEMATICALLY FORMULATED ONE:
public static int Digits1(this Int32 n) =>
n == 0 ? 1 : 1 + (int) Math.Log10(Math.Abs(n));
// TYPICAL PROGRAMMING APPROACH:
public static int Digits2(this Int32 n)
{
int digits = 0;
do { ++digits; n /= 10; } while (n != 0);
return digits;
}
// THE UGLIEST POSSIBLE THING:
public static int Digits3(this Int32 n)
{
n = Math.Abs(n);
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;
}
// THE LOCOMOTIVE PULLING CHARACTERS:
public static int Digits4(this Int32 n) =>
n >= 0 ? n.ToString().Length : n.ToString().Length - 1;
}
Я провел несколько тестов производительности в 5 различных сценариях: 100 000 000 вызовов в цикле for, измеренных с помощью Stopwatch
.
И ПОБЕДИТЕЛЬ ЕСТЬ ...
-1000000000.Digits1() => 1806 ms
-1000000000.Digits2() => 4114 ms
-1000000000.Digits3() => 664 ms <<<
-1000000000.Digits4() => 13600 ms
-1000.Digits1() => 1839 ms
-1000.Digits2() => 1163 ms
-1000.Digits3() => 429 ms <<<
-1000.Digits4() => 9959 ms
0.Digits1() => 166 ms <<<
0.Digits2() => 369 ms
0.Digits3() => 165 ms <<<
0.Digits4() => 7416 ms
1000.Digits1() => 1578 ms
1000.Digits2() => 1182 ms
1000.Digits3() => 328 ms <<<
1000.Digits4() => 9296 ms
1000000000.Digits1() => 1596 ms
1000000000.Digits2() => 4074 ms
1000000000.Digits3() => 581 ms <<<
1000000000.Digits4() => 13679 ms
САМАЯ НЕПРАВИЛЬНАЯ ВОЗМОЖНАЯ ВЕЩЬ!