指定された double の数値で、その「サイズ」(|number|、またはドットの後の数字を除いた桁数として知られている) を返すようにしたい、たとえば:
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
私がよく知らない.netという機能があるに違いありません..
ありがとう。
指定された double の数値で、その「サイズ」(|number|、またはドットの後の数字を除いた桁数として知られている) を返すようにしたい、たとえば:
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
私がよく知らない.netという機能があるに違いありません..
ありがとう。
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の滑らかな関数であることを除きます。
(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 n ≤ x < 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 に評価されます。
((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;
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
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.
コートシー・ムアディブ
int GetLength(double value){
return ((int)Math.Abs(value*10d)).ToString().Length - 1
}
整数への変換と結果の文字列への変換は、値が 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