19


7

.NETで整数の文字列の長さを見つける
NETでは、文字列として表現された整数の長さを文字で見つける最良の方法は何ですか?

e.g.

1 = 1文字+ 10 = 2文字+ 99 = 2文字+ 100 = 3文字+ 1000 = 4文字

明白な答えは、intを文字列に変換してその長さを取得することですが、新しい文字列を作成するオーバーヘッドなしで、可能な限り最高のパフォーマンスを実現したいのです。

6 Answer


37


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));
}

簡単なテストにより、log-methodはint.ToString()。Lengthメソッドより4倍速いことが示されました。

以下のGvSが示すメソッド(ifステートメントを使用)は、ログメソッドよりもさらに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


12


入力が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


1


負の数も処理する必要がある場合は、https://stackoverflow.com/questions/2506476/finding-the-string-length-of-a-integer-in-net/2506541#2506541 [stmax solution]スピン付き:

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;
}


1


できるよ:

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ビットでは、5番目のレベルを追加する必要があります。)


-1


あなたが数学でそれをしたい場合は、これを試すことができます:

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

しかし、これが文字列に変換するよりもはるかに速いかどうかは疑問です