4

我想用给定的双数返回它的“大小”(称为 |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() 是任意函数中的对数函数根据。)

例如,我们有

日志10 (1) = 0.0
日志10 (10) = 1.0
日志10 (100) = 2.0
日志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 的长度为 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 作为 log 10 ()的输入,确保我们计算的长度永远不会低于 0.5 。(我们可以使用 0.1 到 1 之间的任何数字作为截止值,但 0.5 恰好是一个很好的圆形二进制分数。)

此外,我们必须确保在四舍五入之前对数加上 +1 ,以便我们四舍五入的数字始终为非负数。这是因为(int)在 C# 中实际上将负数向上舍入为零。例如,由于 log 10 (0.5) ≈ −0.3,表达式(int)Math.Log10(0.5) + 1(加法前舍入)将计算为 0+1 = 1,而不是预期的 0。

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

Math.Abs将转换为正数(不想计算负号)
(int)将删除小数点后面的数字
ToString()转换为字符串 ===> "12"
Length告诉您有多少个字符存在
边缘情况 where (int)( some number ) == 0, where长度会给你 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

窃取 Quintin 的格式:

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

在此不需要任何技巧(例如,, abs()if

于 2011-07-28T20:20:34.123 回答
1

Courtsey Muad'Dib

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

仅当值在 int 范围内时,转换为整数并将结果转换为字符串才有效。如果您需要超过 20 亿的值,则需要使用日志,或者将双精度值转换为字符串。

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 回答