如何在Javascript中获取浮点数的小数位?

时间:2012-03-04 08:09:21

标签: javascript math floating-point

我想要的是与Number.prototype.toPrecision()几乎完全相反,这意味着当我有数字时,它有多少小数? E.g。

(12.3456).getDecimals() // 4

10 个答案:

答案 0 :(得分:38)

如果有人想知道如何更快地完成这项工作(不转换为字符串),这里有一个解决方案:

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;
}

答案 1 :(得分:23)

一种可能的解决方案(取决于应用程序):

var precision = (12.3456 + "").split(".")[1].length;

答案 2 :(得分:4)

如果“精确”是指“小数位”,那么这是不可能的,因为floats are binary。它们没有具有小数位,并且大多数具有少量小数位的值具有二进制的重复数字,并且当它们被转换回十进制时,不一定产生原始小数号。

任何与浮点数“小数位”一起使用的代码都可能会对某些数字产生意外结果。

答案 3 :(得分:1)

尝试以下

function countDecimalPlaces(number) { 
  var str = "" + number;
  var index = str.indexOf('.');
  if (index >= 0) {
    return str.length - index - 1;
  } else {
    return 0;
  }
}

答案 4 :(得分:1)

没有本机函数来确定小数位数。您可以做的是将数字转换为字符串,然后计算小数分隔符.的偏移量:

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或其他东西代表{{1}}。我不确定上述内容在现实应用程序中的表现如何。

答案 5 :(得分:1)

基于@ 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

答案 6 :(得分:1)

基于@ 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;
}

答案 7 :(得分:0)

以下方法是否有效?

var num = 12.3456
console.log(num - Math.floor(num))

console.log(num - parseInt(num))

答案 8 :(得分: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}`);

没有BigNumber.js

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}`);

答案 9 :(得分:0)

假设数字有效。

Warning in sqlExecute(con, query, sqlParams, fetch = TRUE, stringsAsFactors = FALSE) :
  42000 102 [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near ','.
Warning in sqlExecute(con, query, sqlParams, fetch = TRUE, stringsAsFactors = FALSE) :
  42000 8180 [Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could not be prepared.
Warning: Error in sqlExecute: 42000 102 [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near ','.
42000 8180 [Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could not be prepared.
[RODBCext] Error: SQLExecute failed