JavaScript只显示X小数位,没有舍入

时间:2018-01-06 18:28:55

标签: javascript

我知道之前已经问过这个问题,但是我要解决的答案中存在一些问题。

Here is one I found with the following answer:

function calc(number) {
    var num = number;
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0];
    return with2Decimals
}

我发现这是另一个与我喜欢的方式相同的方式:

function decimalFix(numToBeTruncated, numOfDecimals) { 
    var theNumber = numToBeTruncated.toString(); 
    var pointIndex = theNumber.indexOf('.');
    return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined)); 
}

问题:

除了非常大的十进制数之外,它们大部分都能正常工作。例如,{j}中的数字0.00000001990202020291读为 1.99020202029e-8 ,而不是给我0.000000019如果我想要9个小数位,就会给我 1.99020202 非常偏离基地。

为什么??????

很多人真的很不高兴我/其他人甚至想要解决这个问题,因为这对他们来说似乎是不正统的。它主要与货币有关,如果我只允许在我的计算中如此精确,则不会减少价值的一部分。例如,有时候我需要计算最多6到8个小数位的微交易,但如果我选择回合,我会在这个过程中失去或赚钱。

我感谢有人可以为此问题提供任何帮助或指导。

预期结果:

decimalFix(0.0000000199020202029,9) // 0.000000019

2 个答案:

答案 0 :(得分:3)

你说你需要在小数点右边有6到8位数字,在左边有6到8位数(但通常更像是1-3)。

这就是JavaScript的数字类型(IEEE-754双精度二进制浮点数)可以做到的边缘(如果真的是8.8,超越边缘)。无论小数位于何处,在您丢失信息之前,JavaScript的浮点大约有大约 15个十进制数字。 (无论如何,这不是完整的故事。)

好消息:JavaScript可以使用BigInt类型(通过将您的值乘以100,000,000,因此它们是整数),详情here。在此之前,您可能会考虑使用其中一个现有的"大号"库。

如果你需要使用JavaScript的数字,我会用整数来做。对于整数,您的完全准确范围是-Number.MAX_SAFE_INTEGER - 1Number.MAX_SAFE_INTEGER + 1。那是-9,007,199,254,740,992到9,007,199,254,740,992。有了这个,你可以得到小数字左边的七个数字和它的右边八个(或者当然,左边八个,右七个)。因此,如果我们使用八位精度右边的精度和七位左边(在极限范围内),那就是-9,999,999.999999999,999,999.99999999

计算将使用Math.trunc删除小数部分(假设您要截断为零)。没有科学记数法的输出是微不足道的:

str = String(number);
str = str.substring(0, str.length - 8) + "." + str.substr(-8);

示例:



function toString(number) {
  var str = String(number);
  str = str.substring(0, str.length - 8) + "." + str.substr(-8);
  return str;
}
console.log(toString(999999999999999));
console.log(toString(123456712345678));
console.log(toString(765432187654321));




答案 1 :(得分:0)

  

如果我在计算中只允许这么精确,那么它主要与货币有关,而不会减少价值的一小部分。例如,有时候我需要计算最多6-8个小数位的微交易,但如果我选择回合,我会在这个过程中失去或赚钱。



//rounding to an arbitrary precision
function round(value, precision = 1) {
  return Math.round(value / precision) * precision
}

console.log("round");
console.log(round(1.23456789, 0.001));
console.log(round(1.23456789, 1 / 4));
console.log(round(Date.now(), 1000*60*60)); //the current timestamp rounded to the hour

//rounding to a certain amount of decimal places
function roundToDecimalPlaces(value, decimalPlaces = 0) {
  return round(value, "1e" + (-decimalPlaces));
}

console.log("roundToDecimalPlaces");
console.log(roundToDecimalPlaces(1.23456789, 4));
console.log(roundToDecimalPlaces(0.0000000199020202029, 9));

//and truncating everything after a certain amount of decimal places
function decimalFix(value, decimalPlaces = 0) {
  let precision = "1e" + (-decimalPlaces);
  return Math[value < 0 ? "ceil" : "floor"](value / precision) * precision;
}

console.log("decimalFix");
console.log(decimalFix(0.0000000199020202029, 9));
&#13;
.as-console-wrapper {
  top: 0;
  max-height: 100%!important
}
&#13;
&#13;
&#13;

但是你为什么要首先限制精度呢?如果它取消了视图以及值的显示方式,那么这是错误的方法。

然后你应该看看Number#toFixedNumber#toPrecisionNumber#toLocaleString