C# 如何计算一个数字的总位数?

C# 如何计算一个数字的总位数?,c#,math,numbers,C#,Math,Numbers,如何计算C#中数字的总位数?例如,数字8879789有9个数字。试试这个: myint.ToString().Length 这行得通吗?将一个数字除以10将得到最左边的数字,然后对该数字进行mod 10运算,得到不带第一个数字的数字,并重复该操作,直到得到所有数字为止这取决于你到底想对这些数字做什么。您可以从最后一个数字到第一个数字进行迭代,如下所示: static void Main(string[] args) { long blah = 20948230498204; C

如何计算C#中数字的总位数?例如,数字8879789有9个数字。

试试这个:

myint.ToString().Length

这行得通吗?

将一个数字除以10将得到最左边的数字,然后对该数字进行mod 10运算,得到不带第一个数字的数字,并重复该操作,直到得到所有数字为止

这取决于你到底想对这些数字做什么。您可以从最后一个数字到第一个数字进行迭代,如下所示:

static void Main(string[] args)
{
    long blah = 20948230498204;
    Console.WriteLine(blah.ToString().Length);
}
int i = 855865264;
int NumLen = i.ToString().Length;
int tmp = number;
int lastDigit = 0;
do
{
    lastDigit = tmp / 10;
    doSomethingWithDigit(lastDigit);
    tmp %= 10;
} while (tmp != 0);

不转换为字符串,您可以尝试:

Math.Ceiling(Math.Log10(n));
在ysap评论后的更正:

Math.Floor(Math.Log10(n) + 1);
public static class Int32Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this int n)
    {
        if (n >= 0)
        {
            if (n < 10) return 1;
            if (n < 100) return 2;
            if (n < 1000) return 3;
            if (n < 10000) return 4;
            if (n < 100000) return 5;
            if (n < 1000000) return 6;
            if (n < 10000000) return 7;
            if (n < 100000000) return 8;
            if (n < 1000000000) return 9;
            return 10;
        }
        else
        {
            if (n > -10) return 2;
            if (n > -100) return 3;
            if (n > -1000) return 4;
            if (n > -10000) return 5;
            if (n > -100000) return 6;
            if (n > -1000000) return 7;
            if (n > -10000000) return 8;
            if (n > -100000000) return 9;
            if (n > -1000000000) return 10;
            return 11;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this int n) =>
        n == 0 ? 1 : (n > 0 ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this int n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10) != 0) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this int n) =>
        n.ToString().Length;
}
public static class Int64Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this long n)
    {
        if (n >= 0)
        {
            if (n < 10L) return 1;
            if (n < 100L) return 2;
            if (n < 1000L) return 3;
            if (n < 10000L) return 4;
            if (n < 100000L) return 5;
            if (n < 1000000L) return 6;
            if (n < 10000000L) return 7;
            if (n < 100000000L) return 8;
            if (n < 1000000000L) return 9;
            if (n < 10000000000L) return 10;
            if (n < 100000000000L) return 11;
            if (n < 1000000000000L) return 12;
            if (n < 10000000000000L) return 13;
            if (n < 100000000000000L) return 14;
            if (n < 1000000000000000L) return 15;
            if (n < 10000000000000000L) return 16;
            if (n < 100000000000000000L) return 17;
            if (n < 1000000000000000000L) return 18;
            return 19;
        }
        else
        {
            if (n > -10L) return 2;
            if (n > -100L) return 3;
            if (n > -1000L) return 4;
            if (n > -10000L) return 5;
            if (n > -100000L) return 6;
            if (n > -1000000L) return 7;
            if (n > -10000000L) return 8;
            if (n > -100000000L) return 9;
            if (n > -1000000000L) return 10;
            if (n > -10000000000L) return 11;
            if (n > -100000000000L) return 12;
            if (n > -1000000000000L) return 13;
            if (n > -10000000000000L) return 14;
            if (n > -100000000000000L) return 15;
            if (n > -1000000000000000L) return 16;
            if (n > -10000000000000000L) return 17;
            if (n > -100000000000000000L) return 18;
            if (n > -1000000000000000000L) return 19;
            return 20;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this long n) =>
        n == 0L ? 1 : (n > 0L ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this long n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10L) != 0L) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this long n) =>
        n.ToString().Length;
}

不是直接的C#,但公式是:
n=floor(log10(x)+1)

这里的答案已经适用于无符号整数,但我还没有找到从小数和双精度中获取位数的好方法

public static int Length(double number)
{
    number = Math.Abs(number);
    int length = 1;
    while ((number /= 10) >= 1)
        length++;
    return length;
}
//number of digits in 0 = 1,
//number of digits in 22.1 = 2,
//number of digits in -23 = 2

如果精度很重要,您可以将输入类型从
double
更改为
decimal
,但decimal也有一个限制。

如果它仅用于验证,您可以这样做:
887979789>9999999
使用递归(有时在采访中询问)

的答案,但对于小于1的整数不起作用

这里有一个适用于底片的更新版本:

int digits = n == 0 ? 1 : Math.Floor(Math.Log10(Math.Abs(n)) + 1)

转换为字符串,然后您可以使用.length方法计算数字的总数量。 比如:


假设您的问题是指int,那么以下内容也适用于负/正和零:

Math.Floor((decimal) Math.Abs(n)).ToString().Length
解决方案 以下任何扩展方法都可以完成此工作。他们都把减号看作一个数字,并为所有可能的输入值正确地工作。它们也适用于.NETFramework和.NETCore。但是,根据您对平台/框架的选择,存在相关的性能差异(如下所述)

Int32版本:

Math.Floor(Math.Log10(n) + 1);
public static class Int32Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this int n)
    {
        if (n >= 0)
        {
            if (n < 10) return 1;
            if (n < 100) return 2;
            if (n < 1000) return 3;
            if (n < 10000) return 4;
            if (n < 100000) return 5;
            if (n < 1000000) return 6;
            if (n < 10000000) return 7;
            if (n < 100000000) return 8;
            if (n < 1000000000) return 9;
            return 10;
        }
        else
        {
            if (n > -10) return 2;
            if (n > -100) return 3;
            if (n > -1000) return 4;
            if (n > -10000) return 5;
            if (n > -100000) return 6;
            if (n > -1000000) return 7;
            if (n > -10000000) return 8;
            if (n > -100000000) return 9;
            if (n > -1000000000) return 10;
            return 11;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this int n) =>
        n == 0 ? 1 : (n > 0 ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this int n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10) != 0) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this int n) =>
        n.ToString().Length;
}
public static class Int64Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this long n)
    {
        if (n >= 0)
        {
            if (n < 10L) return 1;
            if (n < 100L) return 2;
            if (n < 1000L) return 3;
            if (n < 10000L) return 4;
            if (n < 100000L) return 5;
            if (n < 1000000L) return 6;
            if (n < 10000000L) return 7;
            if (n < 100000000L) return 8;
            if (n < 1000000000L) return 9;
            if (n < 10000000000L) return 10;
            if (n < 100000000000L) return 11;
            if (n < 1000000000000L) return 12;
            if (n < 10000000000000L) return 13;
            if (n < 100000000000000L) return 14;
            if (n < 1000000000000000L) return 15;
            if (n < 10000000000000000L) return 16;
            if (n < 100000000000000000L) return 17;
            if (n < 1000000000000000000L) return 18;
            return 19;
        }
        else
        {
            if (n > -10L) return 2;
            if (n > -100L) return 3;
            if (n > -1000L) return 4;
            if (n > -10000L) return 5;
            if (n > -100000L) return 6;
            if (n > -1000000L) return 7;
            if (n > -10000000L) return 8;
            if (n > -100000000L) return 9;
            if (n > -1000000000L) return 10;
            if (n > -10000000000L) return 11;
            if (n > -100000000000L) return 12;
            if (n > -1000000000000L) return 13;
            if (n > -10000000000000L) return 14;
            if (n > -100000000000000L) return 15;
            if (n > -1000000000000000L) return 16;
            if (n > -10000000000000000L) return 17;
            if (n > -100000000000000000L) return 18;
            if (n > -1000000000000000000L) return 19;
            return 20;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this long n) =>
        n == 0L ? 1 : (n > 0L ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this long n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10L) != 0L) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this long n) =>
        n.ToString().Length;
}

下面是一个使用二进制搜索的实现。看起来是int32上迄今为止最快的

Int64实现留给读者作为练习(!)

我尝试使用Array.BinarySearch而不是硬编码树,但这大约是速度的一半

编辑: 查找表比二进制搜索快得多,但要消耗更多内存。实际上,我可能会在生产中使用二进制搜索,查找表对于速度增益来说非常复杂,这可能会被软件的其他部分所掩盖

Lookup-Table: 439 ms
Binary-Search: 1069 ms
If-Chain: 1409 ms
Log10: 1145 ms
While: 1768 ms
String: 5153 ms
查找表版本:

Math.Floor(Math.Log10(n) + 1);
public static class Int32Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this int n)
    {
        if (n >= 0)
        {
            if (n < 10) return 1;
            if (n < 100) return 2;
            if (n < 1000) return 3;
            if (n < 10000) return 4;
            if (n < 100000) return 5;
            if (n < 1000000) return 6;
            if (n < 10000000) return 7;
            if (n < 100000000) return 8;
            if (n < 1000000000) return 9;
            return 10;
        }
        else
        {
            if (n > -10) return 2;
            if (n > -100) return 3;
            if (n > -1000) return 4;
            if (n > -10000) return 5;
            if (n > -100000) return 6;
            if (n > -1000000) return 7;
            if (n > -10000000) return 8;
            if (n > -100000000) return 9;
            if (n > -1000000000) return 10;
            return 11;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this int n) =>
        n == 0 ? 1 : (n > 0 ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this int n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10) != 0) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this int n) =>
        n.ToString().Length;
}
public static class Int64Extensions
{
    // IF-CHAIN:
    public static int Digits_IfChain(this long n)
    {
        if (n >= 0)
        {
            if (n < 10L) return 1;
            if (n < 100L) return 2;
            if (n < 1000L) return 3;
            if (n < 10000L) return 4;
            if (n < 100000L) return 5;
            if (n < 1000000L) return 6;
            if (n < 10000000L) return 7;
            if (n < 100000000L) return 8;
            if (n < 1000000000L) return 9;
            if (n < 10000000000L) return 10;
            if (n < 100000000000L) return 11;
            if (n < 1000000000000L) return 12;
            if (n < 10000000000000L) return 13;
            if (n < 100000000000000L) return 14;
            if (n < 1000000000000000L) return 15;
            if (n < 10000000000000000L) return 16;
            if (n < 100000000000000000L) return 17;
            if (n < 1000000000000000000L) return 18;
            return 19;
        }
        else
        {
            if (n > -10L) return 2;
            if (n > -100L) return 3;
            if (n > -1000L) return 4;
            if (n > -10000L) return 5;
            if (n > -100000L) return 6;
            if (n > -1000000L) return 7;
            if (n > -10000000L) return 8;
            if (n > -100000000L) return 9;
            if (n > -1000000000L) return 10;
            if (n > -10000000000L) return 11;
            if (n > -100000000000L) return 12;
            if (n > -1000000000000L) return 13;
            if (n > -10000000000000L) return 14;
            if (n > -100000000000000L) return 15;
            if (n > -1000000000000000L) return 16;
            if (n > -10000000000000000L) return 17;
            if (n > -100000000000000000L) return 18;
            if (n > -1000000000000000000L) return 19;
            return 20;
        }
    }

    // USING LOG10:
    public static int Digits_Log10(this long n) =>
        n == 0L ? 1 : (n > 0L ? 1 : 2) + (int)Math.Log10(Math.Abs((double)n));

    // WHILE LOOP:
    public static int Digits_While(this long n)
    {
        int digits = n < 0 ? 2 : 1;
        while ((n /= 10L) != 0L) ++digits;
        return digits;
    }

    // STRING CONVERSION:
    public static int Digits_String(this long n) =>
        n.ToString().Length;
}
static byte[]_0000llll=新字节[0x10000];
静态字节[]\u fffflll=新字节[0x10001];
静态sbyte[]_hhxxxxx位=新sbyte[0x10000];
//特殊情况下,高DWORD值没有足够的信息来了解如何
//很多数字。
静态ushort[]_lowordSplits=新的ushort[12];
静态sbyte[]_lowordSplitDigitsLT=新sbyte[12];
静态sbyte[]_lowordSplitDigitsGE=新sbyte[12];
静态Int32Extensions()
{
//值为的位数的简单查找表
//00000xxxx(0..65535)
//或FFFFxxxx(-1..-65536)
预计算16();
预计算16();
//Hiword有点复杂
预计算字位数();
}
私有静态void预计算hiworddigits()
{
int b=0;

对于(int-hhh=0;hhh创建一个返回所有数字的方法,以及另一个计算数字的方法:

public static int GetNumberOfDigits(this long value)
{
    return value.GetDigits().Count();
}

public static IEnumerable<int> GetDigits(this long value)
{
    do
    {
        yield return (int)(value % 10);
        value /= 10;
    } while (value != 0);
}
public static int GetNumberOfDigits(此长值)
{
返回值.GetDigits().Count();
}
公共静态IEnumerable GetDigits(此长值)
{
做
{
收益率回报率(整数)(值%10);
数值/=10;
}while(值!=0);
}
在解决这个问题时,我觉得这是一种更直观的方法。我首先尝试了
Log10
方法,因为它看起来很简单,但是它有大量的转角情况和精度问题

我还发现另一个答案中提出的
if
-链看起来有点难看

我知道这不是最有效的方法,但它为您提供了另一个扩展来返回数字以供其他用途(如果不需要在类外使用,您可以将其标记为
private


请记住,它不把负符号看作一个数字。

尝试使用。如果长度不工作,将其转换为字符串FrastLew,表示x=887979789;x.toString().CONTUTE();我会这样做。值得指出的是,如果处理负数,可能会遇到这种方法的问题。(显然是小数,但示例使用了
int
,因此我认为这不是问题。)@Krythic字符串分配是.NET世界的新热潮。新的?不可能。我在2010年就开始疯狂地分配字符串。这真是一个趋势引导者。哈哈。你说得对。这太脏了!@Krythic这不是20世纪80年代,你的计算机有足够的RAM在一次操作期间将一个10个字符的字符串保存到内存中。@MrLore在简单的应用程序中这可能是真的,但在游戏开发世界中,它是一个完全不同的野兽。我恐怕ceil(log10(10))=ceil(1)=1,而不是这个问题应该的2!谢谢,这是一个很好的方法。虽然它没有比int count=0快多少,但在((I/=10)>=1);:(如果你的数字范围包含负数,你需要使用Math.Floor(Math.Log10(Math.Abs(n))+1);@Puterdo Borato:我的性能测试实际上表明,当位数小于5时,你的方法速度更快。通过这个测试,Steve的Math.Floor更快。这对0.Math.Floor(Math.Log10(0)+1)=-2147483648(负infinity+1)不起作用)。请参阅documentation.fails以获取负整数,以及23.00之类的数字。请执行
string。TrimStart('-')
betterlog10(0)是-infinity@Klaus-日志10(0)实际上是未定义的。但是,您是正确的,因为这是一个需要单独测试和处理的特殊情况。对于任何非正整数也是如此。请参阅Steve的answe评论