75

我正在使用 javascript 绑定到一些复选框,并且toFixed(2)没有四舍五入。任何想法为什么它不四舍五入?例如,如果数字是859.385它只显示859.38而不是859.39.

我还读到,toFixed可以根据您使用的浏览器进行不同的舍入,任何人都知道解决这个问题的方法,以便我的 javascript 计算与我的 php 计算相匹配?

var standardprice = parseFloat($('#hsprice_'+this.id.split('_')[1]).val());
var price =  parseFloat($('#hprice_'+this.id.split('_')[1]).val());
var discount =  parseFloat($('#hdiscount_'+this.id.split('_')[1]).val());
var deposit =  parseFloat($('#hdeposit_'+this.id.split('_')[1]).val());

var currSprice = parseFloat($('#hTotalSprice').val());
var currPrice = parseFloat($('#hTotalPrice').val());
var currDiscount = parseFloat($('#hTotalDiscount').val());
var currDeposit = parseFloat($('#hTotalDeposit').val());

currSprice += standardprice;
currPrice += price;
currDiscount += discount;
currDeposit += deposit;

$('#lblTotalSprice').text('$'+addCommas(currSprice.toFixed(2)));
$('#lblTotalPrice').text('$'+addCommas(currPrice.toFixed(2)));
$('#lblTotalDiscount').text('$'+addCommas(currDiscount.toFixed(2)));
$('#lblTotalDeposit').text('$'+addCommas(currDeposit.toFixed(2)));

$('#hTotalSprice').val(currSprice.toFixed(2));
$('#hTotalPrice').val(currPrice.toFixed(2));
$('#hTotalDiscount').val(currDiscount.toFixed(2));
$('#hTotalDeposit').val(currDeposit.toFixed(2));
4

22 回答 22

43

我还没有找到一个 toFixed10 出错的数字。其他人可以吗?

感谢他的回答blg,让我想到了 Mozilla 的toFixed10()方法。

使用它我想出了这个简短的一个班轮,它确实涵盖了这里提到的所有案例......

function toFixed( num, precision ) {
    return (+(Math.round(+(num + 'e' + precision)) + 'e' + -precision)).toFixed(precision);
}
于 2014-05-09T09:01:52.050 回答
24

我将此作为最佳舍入函数用于所有财务数据。您可以对所有有问题的数字进行测试。Javascript 允许某种精度,所以我用它来使几乎每个数字都按预期四舍五入。

function roundTo(n, digits) {
        if (digits === undefined) {
            digits = 0;
        }

        var multiplicator = Math.pow(10, digits);
        n = parseFloat((n * multiplicator).toFixed(11));
        return Math.round(n) / multiplicator;
    }
于 2015-09-16T09:45:19.110 回答
21

在 Chrome 中,toFixed()回合:

859.385 ==> 859.38
859.386 ==> 859.39

当我查看ECMAScript 第 5 版规范.toFixed()(第 15.7.4.5 节)时,我没有看到它明确描述了舍入,尽管它确实描述了一些相当模糊的东西,这可能是 Chrome 已经实现的。

在我看来,如果您想通过显式舍入来控制它,那么您可能应该使用经常建议的解决方法:

var roundedNum = (Math.round( num * 100 ) / 100).toFixed(2);

这将保证您像以前一样获得可预测的舍入。

在这里工作演示:http: //jsfiddle.net/jfriend00/kvpgE/

于 2012-04-04T16:31:09.920 回答
16

由于在 javascripts 的 toFixed-function 中,浮点数5不属于整数的上半部分,如果你有这样的数字,给定的数字会向下舍入:

859.385.toFixed(2) // results in 859.38

事实上,您可以像这里一样附加尾随浮点数(零除外):

859.3851.toFixed(2) // results in 859.39

因此,开发人员倾向于添加数字0.00000000001,以便适当地四舍五入并且不会意外更改数字的值。

所以我想出了一个函数,它根据您希望固定浮点数的位数来添加这样的数字:

    // both parameters can be string or number
    function toFixed(number, decimals) {
        var x = Math.pow(10, Number(decimals) + 1);
        return (Number(number) + (1 / x)).toFixed(decimals)
    }
    toFixed(859.385, 2) //results in 859.39
于 2017-05-16T09:58:41.670 回答
10

与 35.855 一起尝试的另一个好数字是 1.005

我认为 Robert Messerle 的解决方案不能处理 1.005

此处的舍入小数示例https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round $revision/1383484#Decimal_rounding 将数字转换为指数表示法,似乎得到了更好的结果。

我在这里创建了一个小提琴http://jsfiddle.net/cCX5y/2/,它演示了上面的本地 Robert Messerle 示例(称为toFixedB)和来自 Mozilla 文档的示例(称为toFixed10)。

我还没有找到一个 toFixed10 出错的数字。其他人可以吗?

于 2014-04-21T19:26:58.160 回答
9
function roundup(num,dec){
    dec= dec || 0;
    var  s=String(num);
    if(num%1)s= s.replace(/5$/, '6');
    return Number((+s).toFixed(dec));
 }

 var n= 35.855
 roundup(n,2)

/* 返回值:(数字)35.86 */

于 2012-04-04T16:21:10.503 回答
9

toFixed() works correctly! The problem is, that 859.385 has no representation as float at a computer. It is scanned as nearest possible value = 859.384999999999991. And rounding this value to 2 digits is 859.38 and not 859.39.

This is the reasons, that many programming languages (especially old for commerce, e.g. COBOL) support BCD numbers (binary coded decimals), where each digit is coded by itself into 4 bits (like hex without using A-F).

A general solution for prices: Calculate in cent/penny and print NUMBER/100.

A note to other solutions (functions provided here): They may help for some numbers, but mostly fail for e.g. 859.38499999.

于 2019-01-26T15:01:29.553 回答
9

toFixed从来没有四舍五入,也不是为了它。

它几乎不会将浮点数(指数、尾数)转换为定点数(整数、小数)(参见定义)。

执行此操作时,它可能看起来好像是四舍五入,因为四舍五入的数字是最接近原始浮点表示的近似值。

可悲的是,它被广泛传播,toFixed可用于四舍五入……不,它不能,即使顾名思义也与它无关。

如果您需要四舍五入加上toFixed填充:

function round(num, precision) {
  var base = 10 ** precision;
  return (Math.round(num * base) / base).toFixed(precision);
}
于 2019-12-10T13:48:08.067 回答
6

您可以使用 对Math.round()数字进行四舍五入。如果你想四舍五入到一个特定的小数点,你可以使用一些数学:

var result=Math.round(original*100)/100
于 2012-04-04T16:13:57.400 回答
6

如果您希望得到一个数字作为输出,那么请考虑Math.round()其他答案中的技术。

但是,如果您想获得一个字符串作为输出,以呈现给人类,那么通常n.toLocaleString()n.toFixed().

为什么?因为它还会在人类用来阅读的大量数字的头部添加逗号或句点。例如:

var n = 1859.385

n.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})

// Produces  1,859.39  in USA (locale en-US)
// Produces  1 859,39  in France (locale fr-FR)
// Produces  1.859,39  in Germany (locale de-DE)

规范说,当undefined作为第一个参数传递时,将使用用户自己的语言环境(由操作系统指定)。不幸的是,正如链接文档所示,Mozilla 在这种情况下使用 en-US 语言环境,但它可能会在未来符合规范。

于 2018-01-20T13:12:50.667 回答
5

我今天遇到了同样的问题,甚至在其他答案中尝试了建议,我发现我仍然没有收到我预期的结果。最后,当我遇到这个问题时,我正在为我当前的项目使用 AngularJS,我想我检查一下 AngularJS 之前是否已经解决了同样的问题,并且确实他们已经解决了。这是他们使用的解决方案,它非常适合我:

function toFixed(number, fractionSize) {
    return +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
}

在这里找到:AngularJS filters.js 源

于 2015-02-23T16:00:40.553 回答
4

我偶然发现了这个奇怪Number.toFixed的行为。我看到本机功能不可靠,这是不幸的。出于好奇查看答案,我发现他们中的大多数人在数字上表现不佳,35.855因为 TJ Crowder 慷慨地评论了每个答案。

也许这会回答你的问题。

function toFixed(n,precision) {
    var match=RegExp("(\\d+\\.\\d{1,"+precision+"})(\\d)?").exec(n);
    if(match===null||match[2]===undefined) {
        return n.toFixed(precision);
        }
    if(match[2]>=5) {
        return (Number(match[1])+Math.pow(10,-precision)).toFixed(precision);
        }
    return match[1];
    }

正则表达式将您的数字拆分为字符串数组,例如 in toFixed(35.855,2): ["35.855", "35.85", "5"]。如果最后一个数字(在精确截止之后)是>=5,则添加Math.pow(10, -precision)到修剪后的数字。如果您在小数点后 2、3 等处.01截断,这将增加。.002

我不知道这是否万无一失,因为它仍然在浮点数上执行十进制数学,这可能是不可预测的。我可以说它35.855四舍五入35.86

于 2014-01-13T05:28:32.180 回答
4

我知道这是一个老问题,但为什么不做这样的事情:

let TruncatedValueInString = ThenNumberYouWantToTruncate.toFixed(decPlaces + 1).slice(0, -1);
于 2019-01-17T11:21:18.527 回答
4

Joy twindle answer here应该是最好的答案,而不是这么多的hack。

   x = 1859.385;
   x = x.toFixed(2);
   alert(x);

给出错误的四舍五入,即 1859.38 而不是 1859.39

 x = 1859.385;
 x = x.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
 alert(x);

给出正确的四舍五入 1,859.39

唯一的问题是返回的结果是带有千位逗号分隔符的字符串,因此不能用于计算。使用我从堆栈溢出中获得的正则表达式来删除逗号,最终结果是

 x = 1859.385;
 x = x.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
 x=x.replace(/\,/g,'');
 alert(x);

现在返回 1859.39 并可用于计算。正则表达式之前的值即 1,859.39 可用于 html 显示,而未格式化的值 1859.39 可用于计算。

于 2018-01-23T01:47:03.123 回答
4

注意:您可能只需要这个 .toFixed() 解决方案来处理非常大的数字

其他发布的解决方案适用于标准数字(低于 1e21)

如果您想处理非常大的数字和非常小的分数,并且toFixed具有正确的舍入且不损失准确性,并且不必使用库并且具有自包含功能,一种可能的有效解决方案是使用BigInt以避免损失准确性由于内部 javascript 舍入。

下面的函数就是这样做的toFixed(number, [digits])

只需将大数字作为具有所需四舍五入位数的字符串传递即可。数字将被正确四舍五入。

这个概念是将数字分成整数部分和小数部分的常用方法,但用于BigInt()保存这两个部分。此后,在不使用任何 javascript 或数字函数的情况下,根据需要对正数和负数进行舍入和处理,Math以避免损失准确性。

作为非常特殊情况的奖励,其中数字采用非常大的“e”符号,我添加了eToNumber()我在此处发布的函数:https ://stackoverflow.com/a/66072001/11606728将其作为内联过程执行. 如果您想维护短代码并且不关心这些数字,这可能会被删除。[代码中提供了注释以将其删除]。

我已经包含了各种测试用例来测试不同的可能性(其中一些有点奇怪,但确实会发生)。

这个想法可以进一步改进。

希望它是有用的。

/****************************************************************************
* @function    : toFixed(number, [digits])
* @purpose     : Emulate toFixed() for large numbers and
                 large fractional numbers with correct rounding
                 by using the BigInt() built-in Object.
* @version     : 1.01
* @author      : Mohsen Alyafei
* @date        : 03 February 2021
* @param       : {number} [numeric or string] pass large numbers as a string
* @param       : {number} [optional digits]
*              : The number of digits to appear after the decimal point;
*              : this may be a value from 0 and above unlimited.
*              : If this argument is omitted or is negative, it is treated as 0.
*              : Handles large 'e' notation number using the eToNumber() function.digits
*              : See https://stackoverflow.com/a/66072001/11606728
* @returns     : A string representing the given number using fixed-point notation.
****************************************************************************/

function toFixed(num,digits) {
    if (!num && num!==0) return "Cannot read property of null or undefined"; // Can change it to throw Error
    digits<0 && (digits=0);
    digits=digits||0;
    num=eToNumber(num); // Delete this line and function below if larage 'e' notation number are not required
    let wh = (num+="").split((.1).toLocaleString().substr(1,1)), f = wh[1];
    wh = wh[0];
    let fr = (f=f||"0").substr(0,digits), fn = BigInt(fr), w = BigInt(wh), fl = (""+fn).length,
        lZeros = fr.length-fl, minus = wh[0]=="-", inc = (wh<0 || minus) ? BigInt(-1):BigInt(1);
    f[digits]>=5 && (fn+=BigInt(1));
    (fn+="").length > fl && (lZeros-=1);
    lZeros >=0 ? lZeros="0".repeat(lZeros):(fn=fn.substring(1), lZeros="",
               (fn ? w +=inc : ((f[digits]>=5) && (w+=inc))));
    fn = lZeros + fn; L = digits-fn.length;
    L && (fn+="0".repeat(L)); w==0 && minus && (w="-"+w);
    return w+(fn?".":"")+fn;
    }

    //---------------------- Extra Function if needed --------------------------------
    // Delete this function if large 'e' notation number are not required
    // Convert very large 'e' numbers to plain string numbers.
    //--------------------------------------------------------------------------------
    function eToNumber(num) {
        let sign="";
        (num+="").charAt(0)=="-" && (num=num.substring(1),sign ="-");
        let arr = num.split(/[e]/ig); if (arr.length<2) return sign+num;
        let dot=(.1).toLocaleString().substr(1,1), n = arr[0], exp = +arr[1];
        let w = (n=n.replace(/^0+/,'')).replace(dot,''),
          pos = n.split(dot)[1]? n.indexOf(dot)+exp : w.length+exp,
            L = pos-w.length,s=""+BigInt(w);
         w = exp>=0 ? (L>=0 ? s+"0".repeat(L):r()): (pos<=0 ? "0"+dot+"0".repeat(Math.abs(pos))+s:r());
        if (!+w) w=0; return sign+w;
        function r(){return w.replace(new RegExp(`^(.{${pos}})(.)`),`$1${dot}$2`)}}

//================================================
//             Test Cases
//================================================
let r=0; // test tracker
r |= test(35.855,2,"35.86");
r |= test(12.00000015,2,"12.00");
r |= test(35.855,5,"35.85500");
r |= test(35.855,4,"35.8550");
r |= test(1.135,2,"1.14");
r |= test(1.135,3,"1.135");
r |= test(1.135,4,"1.1350");
r |= test(1.135,8,"1.13500000");
r |= test(0.1545,3,"0.155");
r |= test(89.684449,2,"89.68");
r |= test("0.0000001",2,"0.00");
r |= test("0.9993360575508052",3,"0.999");
r |= test("0.999336057550805244545454545",29,"0.99933605755080524454545454500");
r |= test("1.0020739645577939",3,"1.002");
r |= test(0.999,0,"1");
r |= test(0.999,1,"1.0");
r |= test(0.999,2,"1.00");
r |= test(0.975,0,"1");
r |= test(0.975,1,"1.0");
r |= test(0.975,2,"0.98");
r |= test(2.145,2,"2.15");
r |= test(2.135,2,"2.14");
r |= test(2.34,1,"2.3");
r |= test(2.35,1,"2.4");
r |= test("0.0000001",2,"0.00");
r |= test("0.0000001",7,"0.0000001");
r |= test("0.0000001",8,"0.00000010");
r |= test("0.00000015",2,"0.00");
if (r==0) console.log("Tests 01. Standard fractional numbers passed");
//================================================
r=0; // test tracker
r |= test("1234567890123456789444.99",5,"1234567890123456789444.99000");
r |= test("1234567890123456789444.1445",3,"1234567890123456789444.145");
r |= test("1234567890123456789444.14451445144514451745",19,"1234567890123456789444.1445144514451445175");
if (r==0) console.log("Tests 02. Large fractional numbers passed");
//================================================
r=0; // test tracker
r |= test(100,2,"100.00");
r |= test(0,5,"0.00000");
if (r==0) console.log("Tests 03. Non-fractional numbers passed");
//================================================
r=0; // test tracker
r |= test(12345.6789,null,"12346");
r |= test(2.1234,null,"2");
r |= test(12345.6789,undefined,"12346");
r |= test(2.1234,undefined,"2");
r |= test(12345.6789,"","12346");
r |= test(0.1234,"","0");
r |= test(2.1234,"","2");
if (r==0) console.log("Tests 04. Undefined, Null, and Empty Digits passed");
//================================================
r=0; // test tracker
r |= test(1.1155,2,"1.12");
r |= test(1.255,2,"1.26");
r |= test(1.265,2,"1.27");
r |= test(1.275,2,"1.28");
r |= test(1.285,2,"1.29");
r |= test(1.295,2,"1.30");
r |= test(2.05,1,"2.1");
r |= test(2.15,1,"2.2");
r |= test(2.55,1,"2.6");
r |= test(2.65,1,"2.7");
r |= test(2.215,2,"2.22");
r |= test(2.315,2,"2.32");
r |= test(2.715,2,"2.72");
r |= test(2.815,2,"2.82");
r |= test(2.005,2,"2.01");
r |= test(2.105,2,"2.11");
r |= test(2.405,2,"2.41");
r |= test(2.505,2,"2.51");
r |= test(2.605,2,"2.61");
r |= test(2.905,2,"2.91");
r |= test(0.00155,4,"0.0016");
r |= test(2.55,1,"2.6");
r |= test(-2.35,1,"-2.4");
if (r==0) console.log("Tests 05. Correct rounding passed");
//================================================
r=0; // test tracker
r |= test(-1.125,2,"-1.13");
r |= test(-1.15,1,"-1.2");
r |= test(-1.15,1,"-1.2");
r |= test(-1.45,1,"-1.5");
r |= test(-1.65,1,"-1.7");
r |= test(-1.95,1,"-2.0");
r |= test(-2.34,1,"-2.3");
r |= test("-0.024641163062896567",3,"-0.025");
r |= test("-0.024641163062896567",16,"-0.0246411630628966");
r |= test("0.024641163062896567",16, "0.0246411630628966");
r |= test("-0.0246411630628965",16,"-0.0246411630628965");
if (r==0) console.log("Tests 06. Negative numbers rounding passed");
//================================================
r=0; // test tracker
r |= test(.135,2,"0.14");    // without whole part
r |= test(-.135,2,"-0.14");
r |= test("+35.855",2,"35.86");
r |= test("0.0",2,"0.00");
r |= test("-0",2,"-0.00");       //minus 0
r |= test("-0.0",5,"-0.00000");  // minus 0
r |= test("",5,"Cannot read property of null or undefined");        // empty string
r |= test(null,5,"Cannot read property of null or undefined");      //null
r |= test(undefined,5,"Cannot read property of null or undefined"); // undefined
if (r==0) console.log("Tests 07. Special test cases passed");
//================================================
r=0; // test tracker
r |= test(1.1234e1,2,"11.23");      //11.234
r |= test(1.12e2,2,"112.00");       //112
r |= test(-1.1234e2,2,"-112.34");   // -112.34
r |= test(-1.1234e2,4,"-112.3400"); // -112.34
r |= test(-1.1235e2,2,"-112.35");   // -112.35
r |= test(-1.1235e2,1,"-112.4");    // -112.4
if (r==0) console.log("Tests 08. Standard e notation numbers passed");
//================================================

r=0; // test tracker
r |= test("123456789123456789.111122223333444455556666777788889999e+10",16,"1234567891234567891111222233.3344445555666678");
r |= test("1.1235678944556677e2",20,"112.35678944556677000000");
r |= test("99.1235678944556677e2",20,"9912.35678944556677000000");
if (r==0) console.log("Tests 09. Large e notation numbers passed");
//================================================

if (r==0) console.log(`${"-".repeat(22)}\nAll Test Cases Passed.\n${"-".repeat(22)}`);

//================================================
//             Test function
//================================================
function test(n1,n2,should) {
let result = toFixed(n1,n2);
if (result !== should) {console.log(`Output   : ${result}\nShould be: ${should}`);return 1;}
}

于 2021-02-06T11:31:32.443 回答
3

这可能会有所帮助

    tofix2Decimals=function(float){
        if(parseInt(float)==float)return float.toFixed(2);
        $decimals=/\.(\d+)/.exec(float)[1].length;
        $decimals=$decimals>=2?$decimals+1:3;
        float+=Math.pow(10,-$decimals);
        return float.toFixed(2);
    }
于 2013-11-06T04:36:01.677 回答
3

这是由于 JavaScript 的浮点表示而发生的。

尝试这个:

Number.prototype.round = function(digits) {
    digits = Math.floor(digits);
    if (isNaN(digits) || digits === 0) {
        return Math.round(this);
    }
    if (digits < 0 || digits > 16) {
        throw 'RangeError: Number.round() digits argument must be between 0 and 16';
    }
    var multiplicator = Math.pow(10, digits);
    return Math.round(this * multiplicator) / multiplicator;
}

Number.prototype.fixed = function(digits) {
    digits = Math.floor(digits);
    if (isNaN(digits) || digits === 0) {
        return Math.round(this).toString();
    }
    var parts = this.round(digits).toString().split('.');
    var fraction = parts.length === 1 ? '' : parts[1];
    if (digits > fraction.length) {
        fraction += new Array(digits - fraction.length + 1).join('0');
    }
    return parts[0] + '.' + fraction;
}

用法:

var n = 859.385;
console.log(n.round(2)); // 859.39
console.log(n.fixed(2)); // 859.39
console.log(n.round(4)); // 859.385
console.log(n.fixed(4)); // 859.3850
于 2014-03-18T10:48:54.937 回答
2

我想要简洁准确的东西,同时兼具可读性和速度。在阅读了这个问题的所有答案,以及在类似问题中这个特别有用的答案之后,这就是我的解决方案。

const round = (numberToRound, digits = 0, toFixed = false) => {
  const precision = 10 ** digits;
  const n = numberToRound * precision * (1 + Number.EPSILON);
  const roundedNumber = Math.round(n) / precision;
  return toFixed ? roundedNumber.toFixed(digits) : roundedNumber;
};

// rounding by half
console.log(round(0.5));
console.log(round(-0.5));

// fixed decimals
console.log(round(0.5, 2), '( Type:',typeof round(0.5, 2), ')');
console.log(round(0.5, 2, true), '( Type:',typeof round(0.5, 2, true), ')');
console.log(round(-0.5, 2), '( Type:',typeof round(-0.5, 2), ')');
console.log(round(-0.5, 2, true), '( Type:',typeof round(-0.5, 2, true), ')');

// edge cases
console.log(round(1.005, 2) === 1.01);
console.log(round(-1.005, 2) === -1.01);
console.log(round(39.425, 2) === 39.43);
console.log(round(-39.425, 2) === -39.43);
console.log(round(1234.00000254495, 10) === 1234.000002545);
console.log(round(-1234.00000254495, 10) === -1234.0000025449);

// edge cases from other answer's comments.
console.log(round(859.385, 2));
console.log(round(859.3844, 2));
console.log(round(0.000000015, 8))
console.log(round(35.855, 2));

我不喜欢toFixed作为布尔参数,但它现在有效。

于 2020-10-16T05:36:20.090 回答
2

我从林伟丽那里得到了正确的解决方案

function round(number, precision) {
  var shift = function (number, exponent) {
    var numArray = ("" + number).split("e");
    return +(numArray[0] + "e" + (numArray[1] ? (+numArray[1] + exponent) : exponent));
  };
  return shift(Math.round(shift(number, +precision)), -precision);
}

测试结果

round(1.050, 1); // expected 1.1 , result 1.1  (correct)
round(1.005, 2); // expected 1.01, result 1.01 (correct)

round(3456.3456,  3); // 3456.346
round(3456.3456,  2); // 3456.35
round(3456.3456,  1); // 3456.3
round(3456.3456,  0); // 3456
round(3456.3456, -1); // 3460
round(3456.3456, -2); // 3500
round(3456.3456, -3); // 3000

round(undefined, 1        ); // NaN
round(null     , 1        ); // NaN
round("a"      , 1        ); // NaN
round(1        , null     ); // NaN
round(1        , undefined); // NaN
round(1        , "a"      ); // NaN
于 2020-02-06T15:26:24.260 回答
1
function toFixed(num, decimals) {
    return (Math.round((num + Number.EPSILON) * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)
}

我在这里找到了一个有效的答案->最多四舍五入到小数点后 2 位(仅在必要时)

Math.round((num + Number.EPSILON) * 100) / 100

您必须添加Number.EPSILON到四舍五入的数字。

于 2020-10-26T11:09:19.350 回答
0

这对我有用 - “hackish”

function customTofix(value, precision) {
    let decimalVal = 0;
    
    if (value !== null) {
        let appendValue = (((value - Math.floor(value)) !== 0) ? (precision <= (value.toString().split(".")[1].length || 0)) ? '1' : '' : '');
        decimalVal = parseFloat(value.toString() + appendValue).toFixed(precision)
    }

    return decimalVal
}
于 2021-05-20T10:47:36.240 回答
0

这是我的解决方案,包括 3 个功能。

  1. 正确的四舍五入。
  2. 仅以数字显示。(防止科学记数法)
  3. 删除尾随零。

我将@user2823670 的答案这个结合在一起。

var roundUp = function(num, precision) {
    // Return '' if num is empty string
    if (typeof num === 'string' && !num) return '';

    // Remove exponential notation
    num = toPlainString(num);

    // Fixed round up
    var result = +((+(Math.round(+(num + 'e' + precision)) + 'e' + -precision)).toFixed(precision));

    // Remove exponential notation (once again)
    result = toPlainString(result);

    return result;
};

var toPlainString = function(num) {
    return ('' + num).replace(/(-?)(\d*)\.?(\d+)e([+-]\d+)/,
        function(a, b, c, d, e) {
            return e < 0
                ? b + '0.' + Array(1 - e - c.length).join(0) + c + d
                : b + c + d + Array(e - d.length + 1).join(0);
        }
    );
}
于 2020-11-10T07:31:37.583 回答