我想要一个给定的双号来返回它的“大小”(称为| number |,或点后没有数字的数字),例如:
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
必须有一个函数是.net,我不熟悉这样做..
感谢。
答案 0 :(得分:9)
尝试log 10 (max(abs( number ),0.5))+ 1向下舍入。
或者,在实际的C#语法中:
(int)(Math.Log10(Math.Max(Math.Abs(number), 0.5)) + 1)
好的,这是怎么回事?
首先, p = log 10 ( x )是的基础10 logarithm X ;也就是说,10提升到 p -th幂(或1后跟 p 零)的值等于 x 。对数基本上测量数字的长度,除了它是 x 的平滑函数:
(注意,在不提供基数10对数函数的语言中,我们总是可以将其计算为log 10 ( x )= log(< em> x )/ log(10),其中log()是任何基数的对数函数。)
例如,我们有
log 10 (1)= 0.0
log 10 (10)= 1.0
log 10 (100)= 2.0
log 10 (1000)= 3.0
但也包括:
log 10 (5)= 0.69897
log 10 (50)= 1.69897
log 10 (500)= 2.69897
log 10 (5000)= 3.69897
通常, n ≤log 10 ( x )&lt;只要10 n ≤ x &lt; n +1 10 名词 1
看看上面的值,应该很容易看到,要获得整数的基数为10的数字,我们应该将其基数为10的对数向下舍入到最接近的整数并加1(因为我们希望10的长度为2而不是1)。
但是,还有一些边缘情况需要考虑:
首先,原始提问者希望 - 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)= - ∞。为了满足这个要求,我们只需确保我们计算的长度数不能低于0.5,使用最大值,0.5作为log 10 ()的输入。 (我们可以使用介于0.1和1之间的任何数字作为截止值,但0.5恰好是一个很好的圆二进制分数。)
此外,我们必须确保在舍入之前将的对数加1,以便我们舍入的数字始终为非负数。这是因为C#中的(int)
实际上将负数向上舍入为零。例如,由于log 10 (0.5)≈-0.3,表达式(int)Math.Log10(0.5) + 1
(加法前舍入)将评估为0 + 1 = 1而不是预期的0。
答案 1 :(得分:4)
((int)Math.Abs(12.324654)).ToString().Length
Math.Abs
会转换为正数(不想计算负号)
(int)
将删除小数点后的数字
ToString()
转换为字符串===&gt; “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;
答案 2 :(得分: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 - &gt; 2
12 - &gt; 2
0.99 - &gt; 0
1.01 - &gt; 1
901 - &gt; 3
-0.99 - &gt; 0
-9.999 - &gt; 1
答案 3 :(得分:1)
窃取Quintin的格式:
private static int CountAbsoluteDigits(double p) {
int ip = (int)p;
int answer = 0;
while (ip!=0) {
answer++;
ip/=10;
}
return answer;
}
此处不需要技巧(例如,abs()
,if
。
答案 4 :(得分:1)
Courtsey Muad'Dib
int GetLength(double value){
return ((int)Math.Abs(value*10d)).ToString().Length - 1
}
答案 5 :(得分: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