# 获取小数点前的位数

` `static int GetNumberOfDigits(decimal d) { decimal abs = Math.Abs(d); return abs < 1 ? 0 : (int)(Math.Log10(decimal.ToDouble(abs)) + 1); }` `

UPDATE

` `using System; public class Test { public static void Main() { decimal dec = -12345678912345678912345678912.456m; int digits = GetDigits(dec); Console.WriteLine(digits.ToString()); } static int GetDigits(decimal dec) { decimal d = decimal.Floor(dec < 0 ? decimal.Negate(dec) : dec); // As stated in the comments of the question, // 0.xyz should return 0, therefore a special case if (d == 0m) return 0; int cnt = 1; while ((d = decimal.Floor(d / 10m)) != 0m) cnt++; return cnt; } }` `

• `while ((d = decimal.Floor(d / 10m)) != 0m)` ：25ms
• `while ((d = d / 10m) > 1m)` ：32ms
• ToString与math双操作：3ms
• 带有十进制运算的ToString：3ms
• BigInt（查看@Heinzi的答案 ）：2ms

` `Math.Truncate(467.45).ToString().Length` `

` `var myDecimal = 467.45m; Math.Truncate(Math.Abs(myDecimal)).ToString(CultureInfo.InvariantCulture).Length` `

` `Math.Truncate ( Math.Abs ( decValue ) ).ToString( "####" ).Length` `

` `void Main() { digitCount(0.123M); //0 digitCount(493854289.543354345M); //10 digitCount(4937854345454545435549.543354345M); //22 digitCount(-4937854345454545435549.543354345M); //22 digitCount(1.0M); //1 //approximately the biggest number you can pass to the function that works. digitCount(Decimal.MaxValue + 0.4999999M); //29 } int digitCount(decimal num, int count = 0) { //divided down to last digit, return how many times that happened if(Math.Abs(num) < 1) return count; return digitCount(num/10, ++count); //increment the count and divide by 10 to 'remove' a digit }` `
` `decimal d = 467.45M; int i = (int)d; Console.WriteLine(i.ToString(CultureInfo.InvariantCulture).Length); //3` `

` `public static int GetDigitsLength(decimal d) { int i = int(d); return i.ToString(CultureInfo.InvariantCulture).Length; }` `

` `i.ToString().Where(c => Char.IsDigit(c)).ToArray()` `

`Math.Floor(Math.Log10((double)n) + 1);` 是要走的路。

` `Decimal.MaxValue = 79,228,162,514,264,337,593,543,950,335; Int32.MaxValue = 2,147,483,647; //that is, hexadecimal 0x7FFFFFFF;` `

`Math.Floor(n).ToString().Count();` 是坏的，因为它可能包括数千个分离器。

` ` public static int CountNrOfDigitsIfs(decimal d) { var absD = Math.Abs(d); // 1 if (absD < 10M) return 1; // 2 if (absD < 100M) return 2; // 3 if (absD < 1000M) return 3; // 4 if (absD < 10000M) return 4; return CountNrOfDigitsIfsLarge(d); } private static int CountNrOfDigitsIfsLarge(decimal d) { // 5 if (d < 100000M) return 5; // 6 if (d < 1000000M) return 6; // 7 if (d < 10000000M) return 7; // 8 if (d < 100000000M) return 8; // 9 if (d < 1000000000M) return 9; // 10 if (d < 10000000000M) return 10; // 11 if (d < 100000000000M) return 11; // 12 if (d < 1000000000000M) return 12; // 13 if (d < 10000000000000M) return 13; // 14 if (d < 100000000000000M) return 14; // 15 if (d < 1000000000000000M) return 15; // 16 if (d < 10000000000000000M) return 16; // 17 if (d < 100000000000000000M) return 17; // 18 if (d < 1000000000000000000M) return 18; // 19 if (d < 10000000000000000000M) return 19; // 20 if (d < 100000000000000000000M) return 20; // 21 if (d < 1000000000000000000000M) return 21; // 22 if (d < 10000000000000000000000M) return 22; // 23 if (d < 100000000000000000000000M) return 23; // 24 if (d < 1000000000000000000000000M) return 24; // 25 if (d < 10000000000000000000000000M) return 25; // 26 if (d < 100000000000000000000000000M) return 26; // 27 if (d < 1000000000000000000000000000M) return 27; // 28 if (d < 10000000000000000000000000000M) return 28; return 29; // Max nr of digits in decimal }` `

` `<# const int SIGNIFICANT_DECIMALS = 29; const int SPLIT = 5; #> namespace Study.NrOfDigits { static partial class DigitCounter { public static int CountNrOfDigitsIfs(decimal d) { var absD = Math.Abs(d); <# for (int i = 1; i < SPLIT; i++) { // Only 29 significant digits var zeroes = new String('0', i); #> // <#= i #> if (absD < 1<#= zeroes #>M) return <#= i #>; <# } #> return CountNrOfDigitsIfsLarge(d); } private static int CountNrOfDigitsIfsLarge(decimal d) { <# for (int i = SPLIT; i < SIGNIFICANT_DECIMALS; i++) { // Only 29 significant digits var zeroes = new String('0', i); #> // <#= i #> if (d < 1<#= zeroes #>M) return <#= i #>; <# } #> return <#= SIGNIFICANT_DECIMALS #>; // Max nr of digits in decimal } } }` `
` `var sep = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator); var count = d.ToString().TakeWhile(c => c != sep).Count();` `

` `Math.Abs(val).ToString("f0", CultureInfo.InvariantCulture).Length` `

` `Math.Abs(val).ToString("#", CultureInfo.InvariantCulture).Length` `

` `Decimal value = 467.45m; int count = Math.Abs(value).ToString("#", System.Globalization.CultureInfo.InvariantCulture).Length;` `

`#`指定你只想要之前的字符`.`

`System.Globalization.CultureInfo.InvariantCulture`确保您不会从Region选项中获得任何格式化。

` `Math.Floor(Math.Log10(Math.Abs(val)) + 1);` `

TLDR所有其他的答案。 我用PHP写这个，math也是一样的。 （如果我知道C＃我会用那种语言写的）

` `\$input=21689584.999; \$input=abs(\$input); \$exp=0; do{ \$test=pow(10,\$exp); if(\$test > \$input){ \$digits=\$exp; } if(\$test == \$input){ \$digits=\$exp+1; } \$exp++; }while(!\$digits); if(\$input < 1){\$digits=0;} echo \$digits;` `

` `function digitCount(\$input){ \$digits=0; \$input=abs(\$input); while (\$input >= 1) { \$digits++; \$input=\$input/10; //echo \$input."<br>"; } return \$digits; } \$big=(float)(PHP_INT_MAX * 1.1); echo digitCount(\$big);` `

` `SqlDecimal d = new SqlDecimal(467.45M); int digits = d.Precision - d.Scale;` `

`SqlDecimal``System.Data.SqlTypes`命名空间的一部分。 “精度”是有效位数的总数，而“标度”是小数点后的位数。

` `public class test { public static void main(String args[]) { float f = 1.123f; int a = (int) f; int digits = 0; while (a > 0) { digits++; a=a/10; } System.out.println("No Of digits before decimal="+digits); } }` `

` ` const decimal d = 123.45m; const decimal d1 = 0.123m; const decimal d2 = .567m; const decimal d3 = .333m; const decimal d4 = -123.45m; NumberFormatInfo currentProvider = NumberFormatInfo.InvariantInfo; var newProvider = (NumberFormatInfo) currentProvider.Clone(); newProvider.NumberDecimalDigits = 0; string number = d.ToString("N", newProvider); //returns 123 = .Length = 3 string number1 = d1.ToString("N", newProvider); //returns 0 = .Length = 1 string number2 = d2.ToString("N", newProvider); //returns 1 = .Length = 1 string number3 = d3.ToString("N", newProvider); //returns 0 = .Length = 1 string number4 = Math.Abs(d4).ToString("N", newProvider); //returns 123 = .Length = 3` `

` ` public static int NumbersInFrontOfDecimal(decimal input) { NumberFormatInfo currentProvider = NumberFormatInfo.InvariantInfo; var newProvider = (NumberFormatInfo)currentProvider.Clone(); newProvider.NumberDecimalDigits = 0; var absInput = Math.Abs(input); var numbers = absInput.ToString("N", newProvider); //Handle Zero and < 1 if (numbers.Length == 1 && input < 1.0m) { return 0; } return numbers.Length; }` `

``class Program { static void Main() { decimal dec = 467.45m; Console.WriteLine(dec.GetNumberOfDigitsBeforeDecimalPlace()); } } public static class DecimalEx { public static int GetNumberOfDigitsBeforeDecimalPlace(this decimal dec) { var x = new System.Data.SqlTypes.SqlDecimal(dec); return x.Precision - x.Scale; } }` `

` `double i = 1; int numberOfDecimals = 0; while (varDouble % i != varDouble) { numberOfDecimals++; i*=10; } return numberOfDecimals;` `

` `public int Digits(Decimal i) { NumberFormatInfo format = CultureInfo.CurrentCulture.NumberFormat; var str = Math.Abs(i).ToString().Replace(format.NumberGroupSeparator, ""); var index = str.IndexOf(format.NumberDecimalSeparator); var digits = index == -1 ? str.Length : index; }` `

` ` static int GetNumOfDigits(decimal dTest) { int nAnswer = 0; dTest = Math.Abs(dTest); //For loop version for (nAnswer = 0; nAnswer < 29 && dTest > 1; ++nAnswer) { dTest *= 0.1M; } //While loop version //while (dTest > 1) //{ // nAnswer++; // dTest *= 0.1M; //} return (nAnswer); }` `

1. 使用`System.Numerics.BigInteger` ，其构造函数接受一个小数，似乎不会产生任何舍入错误。
2. 使用`BigInteger.Abs()`删除任何标志。
3. 使用带“＃”格式的`BigInteger.ToString()`来禁止可能发生的任何分隔符。

## 码

` `decimal num = 123213123.123123M; int length = BigInteger.Abs((BigInteger)num).ToString("#").Length;` `

` `var number = 476.43; var newNumber = Math.round(number); //get the length of the rounded number, and subtract 1 if the //number is negative (remove the negative sign from the count) int digits = newNumber.ToString().Length - (number < 0 ? 1 : 0);` `

algorithm：

• 转换`|decimal|` string。
• 如果`"."` 存在于小数点之前，否则考虑整数。
• 返回string长度。

` `3.14 --> 3.14 --> "3.14" --> "3.14".Substring(0,1) --> "3".Length --> 1 -1024 --> 1024 --> "1024" --> IndexOf(".") = -1 --> "1024" --> 4` `

` `static int getNumOfDigits (decimal num) { string d = Math.Abs(num).ToString(); if (d.IndexOf(".") > -1) { d = d.Substring(0, d.IndexOf(".")); } return d.Length; }` `

` `decimal value = 467.45; string str = Convert.toString(value); // convert your decimal type to a string string[] splitStr = str.split('.'); // split it into an array (use comma separator assuming you know your cultural context) Console.WriteLine(splitStr[0].Count); // get the first element. You can also get the number of figures after the point by indexing the next value in the array.` `

` `string value = "467.45"; int count = value.split('.')[0] == "0" ? 0 : value.split('.')[0].ToString().Replace("-","").Count();` `

` `var value=467.45; var length=((int)value).ToString().Length` `