JavaScript中获取数字小数位数的最简单方法

90

除了我的示例之外,是否有更好的方法来确定数字的小数位数?

var nbr = 37.435.45;
var decimals = (nbr!=Math.floor(nbr))?(nbr.toString()).split('.')[1].length:0;

所谓更好是指执行速度更快和/或使用本地JavaScript函数,例如nbr.getDecimals()。

提前感谢您!

编辑:

修改了series0ne的答案后,我能够找到的最快方法是:

var val = 37.435345;
var countDecimals = function(value) {
    if (Math.floor(value) !== value)
        return value.toString().split(".")[1].length || 0;
    return 0;
}
countDecimals(val);

速度测试:http://jsperf.com/checkdecimals


3
请看这个非常详细的答案:https://dev59.com/OWkv5IYBdhLWcg3wpCXJ。 - Reinstate Monica Cellio
谢谢,但是提问者指定数字必须有小数点,而我没有。感谢分享有趣的链接。+1 - PhilTrep
@PhilippeTrépanier,在整个事情的大局中,考虑哪个更重要。JavaScript执行速度有多快(我的答案和Pete D的差别很小),以及它下载到客户端的速度?由于Pete D的答案少了几个字节,我个人会陷入选择困境。 - Matthew Layton
@series0ne,我陷入了困境,但由于你对代码的工作原理进行了解释,给出了原型化的方法,并且你的答案比他更快,所以我把正确的答案给了你。 - PhilTrep
@PhilippeTrépanier,好的,我无法反驳! :-) 谢谢。 - Matthew Layton
3个回答

150
Number.prototype.countDecimals = function () {
    if(Math.floor(this.valueOf()) === this.valueOf()) return 0;
    return this.toString().split(".")[1].length || 0; 
}

当绑定到原型时,这允许您直接从数字变量中获取小数位数 (countDecimals();)。

例如:

var x = 23.453453453;
x.countDecimals(); // 9

它的工作原理是将数字转换为字符串,以.拆分并返回数组的最后一部分,如果数组的最后一部分未定义(如果没有小数点,则会发生这种情况),则返回0。

如果您不想将其绑定到原型上,可以直接使用此代码:

var countDecimals = function (value) {
    if(Math.floor(value) === value) return 0;
    return value.toString().split(".")[1].length || 0; 
}

黑色编辑:

我已经修复了这个方法,使得它也可以处理小数,比如0.000000001

Number.prototype.countDecimals = function () {

    if (Math.floor(this.valueOf()) === this.valueOf()) return 0;

    var str = this.toString();
    if (str.indexOf(".") !== -1 && str.indexOf("-") !== -1) {
        return str.split("-")[1] || 0;
    } else if (str.indexOf(".") !== -1) {
        return str.split(".")[1].length || 0;
    }
    return str.split("-")[1] || 0;
}


var x = 23.453453453;
console.log(x.countDecimals()); // 9

var x = 0.0000000001;
console.log(x.countDecimals()); // 10

var x = 0.000000000000270;
console.log(x.countDecimals()); // 13

var x = 101;  // Integer number
console.log(x.countDecimals()); // 0


8
这段代码会对整数类型产生错误:http://jsfiddle.net/3bQqV/。但这可能不是问题的关键。 - A. Wolff
3
使用非常小的小数值(例如0.000000001),也会产生错误。http://jsfiddle.net/yh2Lurf5/ - P Roitto
4
有些国家使用逗号作为小数点分隔符,而不是句点。我曾经用过这个简单的检测技巧来处理这个问题: var isComma = Boolean(parseFloat(1 / 2).toString().indexOf(",") !== -1); 你的最后一行代码可以改成: return value.toString().split((isComma ? "," : "."))[1].length || 0; - Balage
2
现在可选链可用,这可能会使函数更安全(例如NaN)value.toString().split(".")[1]?.length || 0; https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Optionale_Verkettung - Andreas Riedmüller
2
对于某些数字,例如0.0000001,这段代码失效了。 - user3437245
显示剩余17条评论

46

如果您想使代码在处理整数时不抛出错误,并在没有小数的情况下得到结果为0,则可以使用以下代码:

var countDecimals = function (value) { 
    if ((value % 1) != 0) 
        return value.toString().split(".")[1].length;  
    return 0;
};

3
也许更快些:var countDecimals = function (value) { return value % 1 ? value.toString().split(".")[1].length : 0; };该函数用于计算数字参数的小数位数。如果参数有小数部分,则返回小数位数,否则返回0。 - A. Wolff
@OP 你应该在 jsperf 上测试答案,看哪个看起来最好。 - A. Wolff
1
由于JavaScript是一种大小关键的语言,您可以省略else语句。例如.. if(true) return x; return 0; ... 基本上,如果它不返回小数的数量,只需返回0; - Matthew Layton
1
@roasted 已经完成了这个,series0ne 是最快的 http://jsperf.com/checkdecimals - PhilTrep
@PeteD,你的jsperf有误,这是正确的链接:http://jsperf.com/checkdecimals/4 - A. Wolff
显示剩余3条评论

2
正则表达式在计算中非常低效,如果有其他方法的话就不要使用它们。所以我会避免使用它们 :)
类似"Number % 1"的东西返回舍入的小数值(2.3 % 1 = 0.2999999999999998),通常建议尽早使用字符串,因为实数的近似值可能会改变小数位数。
所以你的代码没问题,但我会尝试优化它。
编辑:
function CountDecimalDigits(number)
{
  var char_array = number.toString().split(""); // split every single char
  var not_decimal = char_array.lastIndexOf(".");
  return (not_decimal<0)?0:char_array.length - not_decimal;
}

1
你有一个错位一错误。char_array.length - not_decimal 应该是 char_array.length - not_decimal - 1 - aloisdg
如果您提供一个整数,它也会给出错误的结果。 - ashleedawg

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