在JavaScript中格式化一个正好两位小数的数字

时间:2009-11-13 01:46:18

标签: javascript rounding decimal-point

我有这行代码将我的数字四舍五入到小数点后两位。但是我得到这样的数字:10.8,2.4等。这些不是我的两位小数的想法,所以我如何改进以下内容?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

我想要10.80,2.40等数字。使用jQuery对我很好。

31 个答案:

答案 0 :(得分:935)

要使用定点表示法格式化数字,您只需使用toFixed方法:

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

请注意,toFixed()会返回一个字符串。

重要:请注意,toFixed实际上并非实际上是圆形的,90%的时间它会返回舍入值,但在很多情况下它实际上并不起作用。在你的控制台中试试这个:

2.005.toFixed(2)

你会得到错误的答案

在javascript中没有自然的方法来获取小数舍入,您需要自己的polyfill或使用库。你可以看一下这个https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round

的mozilla的polyfill

答案 1 :(得分:90)

这是一个古老的话题,但仍然排名靠前的Google搜索结果和所提供的解决方案共享相同的浮点小数问题。这是我使用的(非常通用)函数thanks to MDN

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

我们可以看到,我们没有遇到这些问题:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

这种通用性也提供了一些很酷的东西:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

现在,要回答OP的问题,必须输入:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

或者,为了更简洁,更通用的功能:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

您可以使用以下方式调用它:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

各种示例和测试(感谢@t-j-crowder!):

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
function naive(value, exp) {
  if (!exp) {
    return Math.round(value);
  }
  var pow = Math.pow(10, exp);
  return Math.round(value * pow) / pow;
}
function test(val, places) {
  subtest(val, places);
  val = typeof val === "string" ? "-" + val : -val;
  subtest(val, places);
}
function subtest(val, places) {
  var placesOrZero = places || 0;
  var naiveResult = naive(val, places);
  var roundResult = round(val, places);
  if (placesOrZero >= 0) {
    naiveResult = naiveResult.toFixed(placesOrZero);
    roundResult = roundResult.toFixed(placesOrZero);
  } else {
    naiveResult = naiveResult.toString();
    roundResult = roundResult.toString();
  }
  $("<tr>")
    .append($("<td>").text(JSON.stringify(val)))
    .append($("<td>").text(placesOrZero))
    .append($("<td>").text(naiveResult))
    .append($("<td>").text(roundResult))
    .appendTo("#results");
}
test(0.565, 2);
test(0.575, 2);
test(0.585, 2);
test(1.275, 2);
test(1.27499, 2);
test(1234.5678, -2);
test(1.2345678e+2, 2);
test("123.45");
test(10.8034, 2);
test(10.8, 2);
test(1.005, 2);
test(1.0005, 2);
table {
  border-collapse: collapse;
}
table, td, th {
  border: 1px solid #ddd;
}
td, th {
  padding: 4px;
}
th {
  font-weight: normal;
  font-family: sans-serif;
}
td {
  font-family: monospace;
}
<table>
  <thead>
    <tr>
      <th>Input</th>
      <th>Places</th>
      <th>Naive</th>
      <th>Thorough</th>
    </tr>
  </thead>
  <tbody id="results">
  </tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

答案 2 :(得分:41)

我通常会将此添加到我的个人库中,经过一些建议并使用@TIMINeutron解决方案,并使其适应小数长度,然后,这个最适合:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

将适用于所报告的例外情况。

答案 3 :(得分:16)

我不知道为什么我不能在之前的回答中添加评论(也许我绝对是盲目的,不知道),但是我想出了一个使用@Miguel答案的解决方案:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

它的两条评论(来自@bighostkim和@Imre):

  • 问题precise_round(1.275,2)未返回1.28
  • 问题precise_round(6,2)没有返回6.00(正如他所想)。

我的最终解决方案如下:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

正如你所看到的,我不得不添加一些“修正”(它不是它的原因,但是因为Math.round是有损的 - 你可以在jsfiddle.net上查看它 - 这是我知道的唯一方法要解决这个问题)。它为已填充的数字增加了0.001,因此它在十进制值的右侧添加了1三个0 s。所以它应该是安全的。

之后我添加.toFixed(decimal)以始终以正确的格式输出数字(使用正确的小数位数)。

所以这就是它。使用得好;)

编辑:为负数的“修正”添加了功能。

答案 4 :(得分:14)

一种方法是100%确定你得到一个带有2位小数的数字:

(Math.round(num*100)/100).toFixed(2)

如果这导致舍入错误,您可以使用以下内容,正如詹姆斯在他的评论中所解释的那样:

(Math.round((num * 1000)/10)/100).toFixed(2)

答案 5 :(得分:12)

  

toFixed(n)在小数点后提供n个长度; toPrecision(x)的   提供x总长度。

使用以下方法

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

如果您想要修复数字,请使用

result = num.toFixed(2);

答案 6 :(得分:5)

我找不到这个问题的准确解决方案,所以我创建了自己的:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

示例:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

答案 7 :(得分:4)

快速简便

parseFloat(number.toFixed(2))

示例

let number = 2.55435930

let roundedString = number.toFixed(2)    // "2.55"

let twoDecimalsNumber = parseFloat(roundedString)    // 2.55

let directly = parseFloat(number.toFixed(2))    // 2.55

答案 8 :(得分:3)

这是一个简单的

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

alert(roundFloat(1.79209243929,4));

一样使用

Jsfiddle

答案 9 :(得分:3)

@heridev和我在jQuery中创建了一个小函数。

您可以尝试下一步:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

的jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO ONLINE:

http://jsfiddle.net/c4Wqn/

答案 10 :(得分:2)

浮点值的问题在于它们试图用固定的位数表示无限量的(连续)值。很自然地,游戏中肯定会有一些损失,你会被一些价值观念所困扰。

当计算机将1.275存储为浮点值时,它实际上不会记住它是1.275还是1.27499999999999993,甚至是1.27500000000000002。在舍入到两位小数后,这些值应给出不同的结果,但它们不会,因为对于计算机,它们在存储为浮点值后看起来完全相同,并且无法恢复丢失的数据。任何进一步的计算只会累积这种不精确性。

因此,如果精度很重要,则必须从一开始就避免使用浮点值。

是最简单的选择
  • 使用devoted library
  • 使用字符串存储和传递值(伴随字符串操作)
  • 使用整数(例如,您可以传递实际值的百分之一,例如以美分而不是以美元计算的金额)

例如,当使用整数来存储百分之一时,查找实际值的函数非常简单:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

使用字符串,您需要舍入,但它仍然可以管理:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

请注意,此函数会舍入到最近,与零相关,而IEEE 754建议舍入到最近,与偶数联系,作为浮动的默认行为点操作。这些修改留给读者练习:)

答案 11 :(得分:2)

舍入小数值,然后使用toFixed(x)作为预期数字。

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

呼叫

parseDecimalRoundAndFixed(10.800243929,4)=&gt; 10.80 parseDecimalRoundAndFixed(10.807243929,2)=&gt; 10.81

答案 12 :(得分:2)

以下是我的1行解决方案: Number((yourNumericValueHere).toFixed(2));

以下是发生的事情:

1)首先,将.toFixed(2)应用于要舍入小数位的数字。请注意,这会将值从数字转换为字符串。因此,如果您使用的是Typescript,它将抛出这样的错误:

“类型'字符串'不能分配给'number'”

类型

2)要获取数值或将字符串转换为数值,只需在所谓的“字符串”值上应用Number()函数。

为了澄清,请看下面的例子:

示例: 我有一个小数点后最多5位数的金额,我想将它缩短到最多2位小数。我是这样做的:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

答案 13 :(得分:2)

&#13;
&#13;
/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some +ve edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

// testing some -ve edge cases
console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct
&#13;
&#13;
&#13;

答案 14 :(得分:1)

Number(((Math.random() * 100) + 1).toFixed(2))

这将返回1到100的随机数,四舍五入到小数点后两位。

答案 15 :(得分:1)

就这么简单。

var rounded_value=Math.round(value * 100) / 100;

答案 16 :(得分:1)

几个月前,我从这篇文章中得到了一些想法,但是这里没有任何答案,也没有其他帖子/博客的答案能够解决所有情况(例如,测试人员发现的负数和一些“幸运数字”)。最后,我们的测试人员在下面的此方法中未发现任何问题。粘贴我的代码段:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

我也有代码注释(对不起,我已经忘记了所有详细信息)...我在这里发布我的答案以供将来参考:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).

答案 17 :(得分:1)

使用这些示例,在尝试舍入数字1.005时仍会出现错误,解决方案是使用类似Math.js的库或此函数:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

答案 18 :(得分:1)

向下舍入

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

总结

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

最接近的

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}
  

合并https://stackoverflow.com/a/7641824/1889449和   https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm谢谢   它们。

答案 19 :(得分:1)

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

答案 20 :(得分:1)

通过引用使用此响应:https://stackoverflow.com/a/21029698/454827

我构建了一个函数来获取动态的小数:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

这里的工作示例:https://jsfiddle.net/wpxLduLc/

答案 21 :(得分:1)

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

这对我有用:Rounding Decimals in JavaScript

答案 22 :(得分:1)

以下置于某个全球范围内:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

然后尝试

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

更新

请注意,toFixed()只适用于0-20之间的小数位数,即a.getDecimals(25)可能会生成javascript错误,因此为了适应您可能会添加一些额外的检查,即

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}

答案 23 :(得分:0)

你也可以使用.toPrecision()方法和一些自定义代码,并且无论int部分的长度如何,总是向上舍入到第n个十进制数字。

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

你也可以把它作为一个插件,以便更好地使用。

答案 24 :(得分:0)

这很简单,效果和其他任何一样好:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

由于toFixed()只能在数字上调用,不幸的是会返回一个字符串,这会在两个方向上为你完成所有解析。你可以传递一个字符串或一个数字,每次都会得到一个数字!调用parseNumber(1.49)会给你1,而parseNumber(1.49,2)会给你1.50。就像他们最好的一样!

答案 25 :(得分:0)

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

答案 26 :(得分:0)

我正在解决修改器的问题。 仅支持2位小数。

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

答案 27 :(得分:0)

(Math.round((10.2)*100)/100).toFixed(2)

应该产生:10.20

(Math.round((.05)*100)/100).toFixed(2)

应该产生:0.05

(Math.round((4.04)*100)/100).toFixed(2)

应该产生:4.04

答案 28 :(得分:0)

我发现了一种非常简单的方法可以为我解决此问题,并且可以使用或修改:

 idField:'testId ',
 textField: 'test',

答案 29 :(得分:0)

这是https://stackoverflow.com/a/21323330/916734的TypeScript实现。它还会使功能变干,并允许可选的数字偏移。

export function round(rawValue: number | string, precision = 0, fractionDigitOffset = 0): number | string {
  const value = Number(rawValue);
  if (isNaN(value)) return rawValue;

  precision = Number(precision);
  if (precision % 1 !== 0) return NaN;

  let [ stringValue, exponent ] = scientificNotationToParts(value);

  let shiftExponent = exponentForPrecision(exponent, precision, Shift.Right);
  const enlargedValue = toScientificNotation(stringValue, shiftExponent);
  const roundedValue = Math.round(enlargedValue);

  [ stringValue, exponent ] = scientificNotationToParts(roundedValue);
  const precisionWithOffset = precision + fractionDigitOffset;
  shiftExponent = exponentForPrecision(exponent, precisionWithOffset, Shift.Left);

  return toScientificNotation(stringValue, shiftExponent);
}

enum Shift {
  Left = -1,
  Right = 1,
}

function scientificNotationToParts(value: number): Array<string> {
  const [ stringValue, exponent ] = value.toString().split('e');
  return [ stringValue, exponent ];
}

function exponentForPrecision(exponent: string, precision: number, shift: Shift): number {
  precision = shift * precision;
  return exponent ? (Number(exponent) + precision) : precision;
}

function toScientificNotation(value: string, exponent: number): number {
  return Number(`${value}e${exponent}`);
}

答案 30 :(得分:0)

Christian C. Salvadó's answer 之上构建,执行以下操作将输出 Number 类型,并且似乎也可以很好地处理舍入:

const roundNumberToTwoDecimalPlaces = (num) => Number(new Intl.NumberFormat('en-US', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
}).format(num));

roundNumberToTwoDecimalPlaces(1.344); // => 1.34
roundNumberToTwoDecimalPlaces(1.345); // => 1.35

上述内容与已经提到的内容之间的区别在于,您在使用它时不需要 .format() 链接[,并且它输出的是 Number 类型]。< /p>