如何在Javascript中获取浮点数的小数位数?
我想要的是与Number.prototype.toPrecision()几乎相反的数字,这意味着当我有数字时,它有多少个小数?例如如何在Javascript中获取浮点数的小数位数?,javascript,math,floating-point,Javascript,Math,Floating Point,我想要的是与Number.prototype.toPrecision()几乎相反的数字,这意味着当我有数字时,它有多少个小数?例如 (12.3456).getDecimals() // 4 一种可能的解决方案(取决于应用): 试试下面的方法 function countDecimalPlaces(number) { var str = "" + number; var index = str.indexOf('.'); if (index >= 0) { retur
(12.3456).getDecimals() // 4
一种可能的解决方案(取决于应用):
试试下面的方法
function countDecimalPlaces(number) {
var str = "" + number;
var index = str.indexOf('.');
if (index >= 0) {
return str.length - index - 1;
} else {
return 0;
}
}
如果你说的“精度”是指“小数点”,那么这是不可能的,因为。它们没有小数位,大多数小数位的值都有二进制循环数字,当它们转换回小数位时,不一定会产生原始的小数位
任何使用浮点“小数位数”的代码都可能在某些数字上产生意外结果。没有确定小数位数的本机函数。您可以将数字转换为字符串,然后计算十进制分隔符的偏移量
:
Number.prototype.getPrecision = function() {
var s = this + "",
d = s.indexOf('.') + 1;
return !d ? 0 : s.length - d;
};
(123).getPrecision() === 0;
(123.0).getPrecision() === 0;
(123.12345).getPrecision() === 5;
(1e3).getPrecision() === 0;
(1e-3).getPrecision() === 3;
但这是花车的本质,欺骗你<代码>1也可以用
0.00000000989
或其他东西来表示。我不确定上述方法在实际应用中的实际效果如何。对于想知道如何更快地实现这一点(而不转换为字符串)的人,这里有一个解决方案:
function precision(a) {
var e = 1;
while (Math.round(a * e) / e !== a) e *= 10;
return Math.log(e) / Math.LN10;
}
编辑:包含边缘案例的更完整解决方案:
function precision(a) {
if (!isFinite(a)) return 0;
var e = 1, p = 0;
while (Math.round(a * e) / e !== a) { e *= 10; p++; }
return p;
}
基于@blackpla9ue评论并考虑数字指数格式:
function getPrecision (num) {
var numAsStr = num.toFixed(10); //number can be presented in exponential format, avoid it
numAsStr = numAsStr.replace(/0+$/g, '');
var precision = String(numAsStr).replace('.', '').length - num.toFixed().length;
return precision;
}
getPrecision(12.3456); //4
getPrecision(120.30003300000); //6, trailing zeros are truncated
getPrecision(15); //0
getPrecision(120.000)) //0
getPrecision(0.0000005); //7
getPrecision(-0.01)) //2
以下方法有效吗
var num = 12.3456
console.log(num - Math.floor(num))
或
基于@boolean_Type处理指数的方法,但避免使用正则表达式:
function getPrecision (value) {
if (!isFinite(value)) { return 0; }
const [int, float = ''] = Number(value).toFixed(12).split('.');
let precision = float.length;
while (float[precision - 1] === '0' && precision >= 0) precision--;
return precision;
}
这里有两个示例,一个使用库(),另一个不使用库。假设您要检查给定的输入数字(
inputNumber
)的小数位数是否小于或等于最大小数位数(tokenDecimals
)
使用BigNumber.js
import BigNumber from 'bignumber.js'; // ES6
// const BigNumber = require('bignumber.js').default; // CommonJS
const tokenDecimals = 18;
const inputNumber = 0.000000000000000001;
// Convert to BigNumber
const inputNumberBn = new BigNumber(inputNumber);
// BigNumber.js API Docs: http://mikemcl.github.io/bignumber.js/#dp
console.log(`Invalid?: ${inputNumberBn.dp() > tokenDecimals}`);
function getPrecision(numberAsString) {
var n = numberAsString.toString().split('.');
return n.length > 1
? n[1].length
: 0;
}
const tokenDecimals = 18;
const inputNumber = 0.000000000000000001;
// Conversion of number to string returns scientific conversion
// So obtain the decimal places from the scientific notation value
const inputNumberDecimalPlaces = inputNumber.toString().split('-')[1];
// Use `toFixed` to convert the number to a string without it being
// in scientific notation and with the correct number decimal places
const inputNumberAsString = inputNumber.toFixed(inputNumberDecimalPlaces);
// Check if inputNumber is invalid due to having more decimal places
// than the permitted decimal places of the token
console.log(`Invalid?: ${getPrecision(inputNumberAsString) > tokenDecimals}`);
没有BigNumber.js
import BigNumber from 'bignumber.js'; // ES6
// const BigNumber = require('bignumber.js').default; // CommonJS
const tokenDecimals = 18;
const inputNumber = 0.000000000000000001;
// Convert to BigNumber
const inputNumberBn = new BigNumber(inputNumber);
// BigNumber.js API Docs: http://mikemcl.github.io/bignumber.js/#dp
console.log(`Invalid?: ${inputNumberBn.dp() > tokenDecimals}`);
function getPrecision(numberAsString) {
var n = numberAsString.toString().split('.');
return n.length > 1
? n[1].length
: 0;
}
const tokenDecimals = 18;
const inputNumber = 0.000000000000000001;
// Conversion of number to string returns scientific conversion
// So obtain the decimal places from the scientific notation value
const inputNumberDecimalPlaces = inputNumber.toString().split('-')[1];
// Use `toFixed` to convert the number to a string without it being
// in scientific notation and with the correct number decimal places
const inputNumberAsString = inputNumber.toFixed(inputNumberDecimalPlaces);
// Check if inputNumber is invalid due to having more decimal places
// than the permitted decimal places of the token
console.log(`Invalid?: ${getPrecision(inputNumberAsString) > tokenDecimals}`);
假设数字是有效的
let number = 0.999;
let noOfPlaces = number.includes(".") //includes or contains
? number.toString().split(".").pop().length
: 0;
15-Math.ceil(Math.log(x)/Math.log(10))
可能的重复:x=12.3456;var precision=String(x).replace('.','').length-x.toFixed().length但是这个数字的精度是6。正如@theonlygusti指出的,这不是“精度”。它是“刻度”,或“小数点”。精度是关于有效数字(1234=4 prec,1.234=4 prec)好的,很高兴知道。无论如何,我只讨论十进制数字的显示方式,所以将它们更改为字符串以“.”分隔似乎是你的答案。如果你将NaN传递给此,它将进入无限循环。这是一个很好的答案,但我建议你检查边缘情况,如NaN或无穷大,以避免无限循环。另外,如果您返回Math.round(Math.log(e)/Math.LN10)
,结果可能会更好。与上面的字符串答案相比,只是为了好玩,请将它放在一个jsperf中。大约快8倍:请注意,如果输入无效(例如空字符串),现有版本仍然会导致无休止的循环。浮点错误在大小写n=0.443999999995
,精度(n)==18
,而面值精度应为17。(1.0+)。拆分(“.”[1]。长度
给出错误,因为split
返回一个字符,因此我们无法访问它的第二个([1]
)元素。类似的内容应该可以工作:函数getPrecision(number){var n=number.toString().split(.“”);返回n.length>1?n[1]。长度:0;}此“已接受”答案在一般情况下不正确,正如Piotr上面提到的。另外,这个问题是一个.split('.')[1].length
在获取小数点计数时适用于所有情况。当您输入不带小数的数字或输入带点的字符串(例如wat.wat
)时,它将失败,改进:函数精度(num){if(isNaN(+num))返回0;const decimals=(num+“”)。拆分('.)[1];if(decimals)返回小数点长度;返回0;}