我想要的是与Number.prototype.toPrecision()几乎相反的功能,也就是说,当我有一个数字时,它有多少位小数?例如:
(12.3456).getDecimals() // 4
我想要的是与Number.prototype.toPrecision()几乎相反的功能,也就是说,当我有一个数字时,它有多少位小数?例如:
(12.3456).getDecimals() // 4
如果有人想知道如何更快地做到这一点(而不需要转换为字符串),这里是一个解决方案:
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;
}
Math.round(Math.log(e) / Math.LN10)
,可能会更好。 - Justinn = 0.44399999999999995
,precision(n) == 18
的情况下出现,而面值精度应为17。 - hackape一个可能的解决方案(取决于应用程序):
var precision = (12.3456 + "").split(".")[1].length;
split
方法返回的是一个字符数组,因为它将字符串拆分成了单个字符。所以 (1.0 + "").split(".")[1].length;
报错了,因为我们无法访问单个字符数组的第二个元素([1]
)。 - Piotr Aleksander Chmielowski(12.3456 + '.').split('.')[1].length;
可以适用于所有情况,用来获取小数位数。 - Heath Duttonwat.wat
)时,它将失败。改进后的代码如下:function precision(num) {
if (isNaN(+num)) return 0;
const decimals = (num + '').split('.')[1];
if (decimals) return decimals.length;
return 0;
}
- mtx没有原生函数可以确定小数点位数。您可以将数字转换为字符串,然后计算小数点分隔符.
的偏移量来确定小数点位数:
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 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
function countDecimalPlaces(number) {
var str = "" + number;
var index = str.indexOf('.');
if (index >= 0) {
return str.length - index - 1;
} else {
return 0;
}
}
基于@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;
}
5622890.31 次/秒(比原来慢了 91.58%):
function precision (n) {
return (n.toString().split('.')[1] || '').length
}
precision(1.0123456789)
33004904.53次操作/秒(慢50.58%):
function precision (n) {
let e = 1
let p = 0
while(Math.round(n * e) / e !== n) {
e *= 10
p++
}
return p
}
precision(1.0123456789)
每秒执行62610550.04个操作(比原来慢6.25%):
function precision (n) {
let cur = n
let p = 0
while(!Number.isInteger(cur)) {
cur *= 10
p++
}
return p
}
precision(1.0123456789)
66786361.47 ops/s(最快):
function precision (n) {
let cur = n
let p = 0
while(Math.floor(cur) !== cur) {
cur *= 10
p++
}
return p
}
precision(1.0123456789)
let number = 0.999;
let noOfPlaces = number.includes(".") //includes or contains
? number.toString().split(".").pop().length
: 0;
这里有两个例子,一个使用库(BigNumber.js),另一个不使用库。假设您想检查给定的输入数字(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}`);
15 - Math.ceil(Math.log(x) / Math.log(10))
- Ignacio Vazquez-Abramsx = 12.3456; var precision = String(x).replace('.', '').length - x.toFixed().length;
- Malitta Nx = 0.0000005
,因为它是以指数格式表示的:5e-7
. - Boolean_Type