使用JavaScript获取数字的位数

183

正如我帖子的标题所示,我想知道var number有多少位数字。例如:如果number = 15;,我的函数应该返回2。目前,它看起来像这样:

function getlength(number) {
  return number.toString().length();
}

但 Safari 表示由于 TypeError ,它无法正常工作:

'2' is not a function (evaluating 'number.toString().length()')

正如您所看到的,'2'实际上是正确的解决方案。但为什么它会出现not a function的错误?


1
12/2021 - 在数字前添加引号,例如(number+'').length,将自动将内容转换为字符串,然后您可以使用.length - Mohamed Reda
20个回答

310

length 是一个属性而不是方法。你不能调用它,因此不需要括号()

function getlength(number) {
    return number.toString().length;
}

更新: 如评论中所讨论的那样,以上示例对于浮点数将无法使用。为了使其起作用,我们可以使用 String(number).replace('.', '').length 来去掉小数点,或使用正则表达式计算数字:String(number).match(/\d/g).length

在速度方面,获取给定数字中数字数量的潜在最快方法是通过数学计算。对于正整数,有一个非常好的使用 log10 的算法:

var length = Math.log(number) * Math.LOG10E + 1 | 0;  // for positive integers

对于所有类型的整数(包括负数),有一种出色的优化解决方案,来自@Mwr247,但是要小心使用Math.log10,因为许多旧版浏览器不支持它。因此,用Math.log(x) * Math.LOG10E替换Math.log10(x)将解决兼容性问题。
由于十进制数的快速数学解决方案很难实现,因为存在浮点数计算的众所周知的行为,因此采用转换为字符串的方法会更加简单和可靠。如@streetlogics所述,快速转换可以通过简单的数字与字符串连接完成,从而将replace解决方案转换为:
var length = (number + '').replace('.', '').length;  // for floats

3
获取数字位数的好方法,但如果是小数呢?例如,12.5,那么您的函数将返回4而不是3... - Scarecrow
3
否则,可以使用类似于 number.toString().match(/\d/g).length 这样的代码。 - VisioN
1
@Bakudan - 这个答案似乎已经被修复了。你现在可以删除你的两条评论来批评它(这样未来的人就不会感到困惑,认为这个答案中的代码无法工作)。 - ArtOfWarfare
1
| 0 的目的是什么?我会认为它是某种隐式转换,因为任何 OR 0 的东西都将是它本身,但我真的很希望能得到解释。 - 3ocene
1
@3ocene 猜得不错!该值保持不变,但在背后被转换为整数。 x | 0 只是 Math.floor(x) 的另一个简短而快速的版本,它将数字向下舍入。您可以使用 ~~x 实现相同的效果。下面的问题提供了更多有关此主题的解释:https://dev59.com/kmox5IYBdhLWcg3wq2EC。 - VisioN
显示剩余5条评论

98

这里是一个数学答案(也适用于负数):

function numDigits(x) {
  return Math.max(Math.floor(Math.log10(Math.abs(x))), 0) + 1;
}

以下是上述代码的优化版本(使用更高效的位运算):

function numDigits(x) {
  return (Math.log10((x ^ (x >> 31)) - (x >> 31)) | 0) + 1;
}

首先,我们通过获取输入的绝对值来允许负数正确工作。然后我们运行log10操作,以给出输入是10的多少次幂(如果您使用另一个基数,则会使用该基数的对数),这就是数字的数量。然后我们将输出向下取整,只获取该整数部分。最后,我们使用max函数来修复小数值(0和1之间的任何分数值都返回1,而不是负数),并将1添加到最终输出中以获得计数。

以上假设(根据您的示例输入)您希望计算整数中的数字数量(因此12345 = 5,因此12345.678也为5)。如果您想计算值中的总数字数(因此12345.678 = 8),则在上述任一函数的“return”之前添加此内容:

x = Number(String(x).replace(/[^0-9]/g, ''));

请注意,在JavaScript中,位运算适用于32位值(最大为2,147,483,647)。因此,如果您期望使用比这更大的数字,请不要使用位运算版本,否则它将无法正常工作。

5
请注意:Math.log10是ES6函数,用于JavaScript中的对数运算。有关详细信息,请参阅MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 - Tx3
4
好的注意!值得庆幸的是,Math.LOG10E自ES1版本就存在了,这意味着Math.log(x) * Math.LOG10E的兼容性良好。 - Mwr247
2
@lokhmakov 这是因为您提供的第二个数字超过了JavaScript的最大32位整数值,这使得按位运算符(^, >>, |)无法正确处理。 - Mwr247
优化版本对于非常大的数字无法正常工作,例如 console.log(numDigits(12345678901234567890) );。但另一个版本可以正常工作! - Justin
2
正确。人们应该期望JS仅适用于最大安全整数,而该数字比几乎任何人需要的数字都要大得多。我正在开发一个使用非常大的数字的游戏,由于这种限制,无法使用优化代码,并想评论以避免其他人在后续出现破损代码的情况。顺便说一句,回答非常好。 - Justin
显示剩余8条评论

23

由于这个问题通过谷歌搜索“javascript get number of digits”而被提出,我想说有一个更短的替代方案,该方案依赖于内部转换为您完成:

var int_number = 254;
var int_length = (''+int_number).length;

var dec_number = 2.12;
var dec_length = (''+dec_number).length;

console.log(int_length, dec_length);

产量

3 4

4
一个快速的 jsperf 显示这也要快得多(也就是说,快10倍或更多):http://jsperf.com/number-tostring-vs-number。 - Ledivin
3
注意!点号也算作数字。 (在十进制数中) - Sebastian Norr
1
修正代码,使其跳过小数点:var dec_length = ('' + dec_number).replace('.', '').length - WtFudgE

10

获取长度很简单,只需:

  `${NUM}`.length

其中NUM是要获取长度的数字


它不能处理负值(负号会增加额外的字符)或十进制值(逗号会增加额外的字符)。此外,本地化可以在数字组之间添加分隔符(例如10'000)。提及这一点作为您回答的一个警告是值得的。 - Reinis

7

你可以在这个技巧中使用:

(''+number).length

4
你可以使用 Math.abs 函数将负数转换为正数并保留正数。然后,您可以将数字转换为字符串并提供长度。
Math.abs(num).toString().length;

我发现这种方法最简单且效果很好。但是,如果你确定会得到正数,那么只需将它转换为字符串,然后使用length即可。

num.toString().length

3

var i = 1;
while( ( n /= 10 ) >= 1 ){ i++ }

23432          i = 1
 2343.2        i = 2
  234.32       i = 3
   23.432      i = 4
    2.3432     i = 5
    0.23432


2
如果需要小数点后的数字,可以将数字拆分并计算第二部分(小数点后)的长度。
function countDigits(number) {
    var sp = (number + '').split('.');
    if (sp[1] !== undefined) {
        return sp[1].length;
    } else {
        return 0;
    }
}

2

我还在学习JavaScript,但我以前用C语言编写了这个函数,它使用数学和while循环而不是字符串,所以我为JavaScript重新编写了它。也许可以通过递归的方式来做到这一点,但我仍然没有真正掌握这个概念:(这是我能想到的最好的方法。我不确定它能够处理多大的数字,但当我输入一百位数字时它确实能够工作。

function count_digits(n) {
    numDigits = 0;
    integers = Math.abs(n);

    while (integers > 0) {
        integers = (integers - integers % 10) / 10;
        numDigits++;
    }
    return numDigits;
}

编辑:仅适用于整数值


2
注意:此函数将忽略小数点后的数字。如果你想要包括小数,则删除 Math.floor()。直接查看以下内容!
function digitCount ( num )
{
     return Math.floor( num.toString()).length;
}

 digitCount(2343) ;

// ES5+

 const digitCount2 = num => String( Math.floor( Math.abs(num) ) ).length;

 console.log(digitCount2(3343))

基本上,这里发生了什么。 toString()String() 是将数字转换为字符串的相同内置函数,一旦转换完成,我们就可以通过内置函数 length 找到字符串的长度。
注意:但是这个函数对于负数不起作用,如果您想尝试负数,请查看 此答案 或简单地将 Math.abs() 放入其中;
祝愿您好运!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接