Подтвердить что ты не робот

Поиск длины строки целого в .NET.

В .NET какой лучший способ найти длину целого в символах, если он был представлен как строка?

например.

1 = 1 символ
10 = 2 символа
99 = 2 символа
100 = 3 символа
1000 = 4 символа

Очевидным ответом является преобразование int в строку и получение его длины, но я хочу, чтобы была максимально возможная производительность без накладных расходов на создание новой строки.

4b9b3361

Ответ 1

вы можете использовать logartihms для вычисления длины int:

public static int IntLength(int i) {
  if (i <= 0) throw new ArgumentOutOfRangeException();

  return (int)Math.Floor(Math.Log10(i)) + 1;
}

проходит тест:

[Test]
public void TestIntLength() {
  Assert.AreEqual(1, IntLength(1));
  Assert.AreEqual(1, IntLength(9));
  Assert.AreEqual(2, IntLength(10));
  Assert.AreEqual(2, IntLength(99));
  Assert.AreEqual(3, IntLength(100));
  Assert.AreEqual(3, IntLength(999));
  Assert.AreEqual(4, IntLength(1000));
  Assert.AreEqual(10, IntLength(int.MaxValue));
}

быстрый тест показал, что лог-метод в 4 раза быстрее, чем метод int.ToString(). Метод длины.

метод, показанный ниже GvS (с использованием if-statements), в 6 раз (!) быстрее, чем метод журнала:

public static int IntLengthIf(int i) {
  if (i < 10) return 1;
  if (i < 100) return 2;
  if (i < 1000) return 3;
  if (i < 10000) return 4;
  if (i < 100000) return 5;
  if (i < 1000000) return 6;
  if (i < 10000000) return 7;
  if (i < 100000000) return 8;
  if (i < 1000000000) return 9;
  throw new ArgumentOutOfRangeException();
}

здесь указаны точные тайминги для чисел от 1 до 10000000:

IntLengthToString: 4205ms
IntLengthLog10: 1122ms
IntLengthIf: 201ms

Ответ 2

Если вход находится в диапазоне 0-10000

if (i < 10) return 1;
if (i < 100) return 2;
if (i < 1000) return 3;
if (i < 10000) return 4;
// etc

Ответ 3

Вы можете использовать что-то вроде этого:

        int integer = 100;

        int charachtersCount = 0;
        while (integer > 0)
        {
            integer = integer/10;
            charachtersCount++;
        }

Но вам действительно нужно оптимизировать это? Я бы предпочел использовать строку (выглядит намного лучше):

integer.ToString().Length

Ответ 4

Если вам нужно иметь дело с отрицательными номерами, вы можете взять решение stmax со спином:

public static int IntLength(int i) { 
  if (i == 0) return 1; // no log10(0)
  int n = (i < 0) ? 2 : 1;
  i = (i < 0) ? -i : i;

  return (int)Math.Floor(Math.Log10(i)) + n; 
} 

Ответ 5

Вы можете сделать:

int ndig = 1;
if (n < 0){n = -n; ndig++;}
if (n >= 100000000){n /= 100000000; ndig += 8;}
if (n >=     10000){n /=     10000; ndig += 4;}
if (n >=       100){n /=       100; ndig += 2;}
if (n >=        10){n /=        10; ndig += 1;}

или что-то в этом роде. Он принимает 4 сравнения и 0-4 деления.

(На 64 битах вам нужно добавить пятый уровень.)

Ответ 6

Если вы хотите сделать это по математике, вы можете попробовать следующее:

int integer = 100
int charCount = (int) Math.Ceiling(Math.Log10(integer+1));

Я сомневаюсь, что это намного быстрее, чем преобразование в строку, хотя