4

指定された double の数値で、その「サイズ」(|number|、またはドットの後の数字を除いた桁数として知られている) を返すようにしたい、たとえば:

12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1

私がよく知らない.netという機能があるに違いありません..

ありがとう。

4

6 に答える 6

12

log 10 (max(abs( number ), 0.5)) + 1 を切り捨ててみてください。

または、実際の C# 構文では次のようになります。

(int)(Math.Log10(Math.Max(Math.Abs(number), 0.5)) + 1)

わかりました、それはどのように機能しますか?

まず、  p = log 10 ( x ) は x の 10を底とする対数です。つまり、10 のp乗 (または 1 の後にp個のゼロが続く) がxに等しくなるような値です。対数は、基本的に数値の長さを測定しますが、xの滑らかな関数であることを除きます。

x の 10 を底とする対数のグラフ

(10 を底とする対数関数を提供しない言語では、いつでも log 10 ( x ) = log( x ) / log(10) として計算できることに注意してください。ここで、log() は任意の対数関数です)ベース。)

たとえば、

log 10 (1) = 0.0
log 10 (10) = 1.0
log 10 (100) = 2.0
log 10 (1000) = 3.0

だけでなく、例えば:

ログ10 (5) = 0.69897
ログ10 (50) = 1.69897
ログ10 (500) = 2.69897
ログ10 (5000) = 3.69897

一般に、  10 nx < 10 n +1の場合は常にn ≤ log 10 ( x ) < n +1です。

上記の値を見ると、10 を底とする整数の桁数を取得するには、10 を底とする対数を最も近い整数に丸めて 1 を足す必要があることが簡単にわかります ( 10 の長さは 1 ではなく 2 になります)。

ただし、考慮すべきエッジケースがいくつかあります。

最初に、元の質問者は − xの長さがxの長さと等しくなることを望んでいました。対数は正の数に対してのみ定義されるため、xをその絶対値に置き換えて、常に正の値にします。

第二に、元の質問者は、0 と 1 の間の数字の長さがゼロであることも望んでいました。ただし、対数は、任意の大きな負の値を取ることができます。

log 10 (0.1) = −1.0
log 10 (0.01) = −2.0
log 10 (0.001) = −3.0
log 10 (0.0001) = −4.0

実際、log 10 (0) = −∞ です。この要件を満たすために、log 10への入力として 0.5 と最大値を使用して、計算する長さが 0.5 を下回らないようにするだけです ()。(カットオフとして 0.1 から 1 の間の任意の数値を使用できますが、0.5 はたまたま丸めの 2 進分数です。)

また、丸める前に必ず対数に +1 を加算して、丸める数値が常に負にならないようにする必要があります。これ(int)は、C# では実際に負の数をゼロに向けて切り上げるためです。たとえば、log 10 (0.5) ≈ −0.3 であるため、式(int)Math.Log10(0.5) + 1(加算前の丸め) は、予想される 0 ではなく 0+1 = 1 に評価されます。

于 2011-07-28T20:08:04.823 に答える
6
((int)Math.Abs(12.324654)).ToString().Length

Math.Abs正の数に変換します (負の符号を数えたくない)
(int)小数点以下の桁を削除します
ToString()文字列に変換します ===> "12"
Lengthは文字数を示し
ます(int)( some number ) == 0長さはあなたに1を与えようとしています--あなたはこれを望まないかもしれないので、可能性に注意してください

今、あなたができることは、これを拡張メソッドにすることです....

public static class Utils
{
   public static int Size(this double n)
   {
     int i = (int)Math.Abs(n);
     if ( i == 0 ) return 0;
     return  i.ToString().Length;
   }
}

12.324654.Size() == 2;
于 2011-07-28T20:10:08.240 に答える
2

0長さゼロを返す数字を考慮して、以下のようなことを行うことができます

private static int CountAbsoluteDigits(double p) {
    int absolute = (int)Math.Abs(p);
    if (0 == absolute)
        return 0;
    else
        return absolute.ToString().Length;
}

...

var length = CountAbsoluteDigits(12.324654);

これは、あなたが提供した数字で得た出力です..

12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1

于 2011-07-28T20:16:08.993 に答える
1

Stealing Quintin's format:

private static int CountAbsoluteDigits(double p) {
    int ip = (int)p;
    int answer = 0;
    while (ip!=0) {
        answer++;
        ip/=10;
    }
    return answer;
}

No trick (e.g., abs(), if) required in this.

于 2011-07-28T20:20:34.123 に答える
1

コートシー・ムアディブ

int GetLength(double value){
    return ((int)Math.Abs(value*10d)).ToString().Length - 1
}
于 2011-07-28T20:27:55.097 に答える
0

整数への変換と結果の文字列への変換は、値が int の範囲内にある場合にのみ機能します。20 億を超える値が必要な場合は、ログを操作するか、double を文字列に変換する必要があります。

static int GetLength(double d)
{
    d = Math.Abs(d);
    if (d < 1.0) return 0;
    if (double.IsInfinity(d)) return int.MaxValue;
    if (double.IsNaN(d)) return 0;
    return (int)Math.Floor(Math.Log10(d)) + 1;
}

static int GetLength2(double d)
{
    d = Math.Abs(d);
    if (d < 1.0) return 0;
    if (double.IsInfinity(d)) return int.MaxValue;
    if (double.IsNaN(d)) return 0;
    string s = d.ToString("E"); // returns a string in the format "1.012435E+001"
    return int.Parse(s.Substring(s.Length - 3)) + 1;
}

static void Test(double d) { Debug.WriteLine(d + " -> " + GetLength(d) + ", " + GetLength2(d)); }

static void Main(string[] args)
{
    Test(0);
    Test(0.125);
    Test(0.25);
    Test(0.5);
    Test(1);
    Test(2);
    Test(10);
    Test(10.5);
    Test(10.25);
    Test(10.1243542354235623542345234523452354);
    Test(999999);
    Test(1000000);
    Test(1000001);
    Test(999999.111);
    Test(1000000.111);
    Test(1000001.111);
    Test(double.MaxValue);
    Test(double.MinValue);
    Test(double.PositiveInfinity);
    Test(double.NegativeInfinity);
    Test(double.NaN);
    Test(double.Epsilon);
}

結果:

0 -> 0, 0
0.125 -> 0, 0
0.25 -> 0, 0
0.5 -> 0, 0
1 -> 1, 1
2 -> 1, 1
10 -> 2, 2
10.5 -> 2, 2
10.25 -> 2, 2
10.1243542354236 -> 2, 2
999999 -> 6, 6
1000000 -> 7, 7
1000001 -> 7, 7
999999.111 -> 6, 6
1000000.111 -> 7, 7
1000001.111 -> 7, 7
1.79769313486232E+308 -> 309, 309
-1.79769313486232E+308 -> 309, 309
Infinity -> 2147483647, 2147483647
-Infinity -> 2147483647, 2147483647
NaN -> 0, 0
4.94065645841247E-324 -> 0, 0
于 2011-07-28T20:56:29.123 に答える