English 中文(简体)
Javascript to Fixed 不四舍五入
原标题:Javascript toFixed Not Rounding
  • 时间:2012-04-04 16:06:44
  •  标签:
  • javascript

使用javascript对一些检查箱进行约束的Im,而toFixed(2)则没有四舍五入。 它为什么不四舍五入? 例如,如果该编号为859.385,则该编号仅显示859.38而不是859.39

I ve also read that the toFixed can round differently depending on which browser you are using, anyone know of a way around this so that my javascript calculations match my php calculations?

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));
问题回答

我尚未发现有数人认为十大错。 谁是谁?

由于blg ,回答,其中指明了我:;https://developer.mozilla.org/en-US/docs/Web/Javagust/Reference/Global_Objects/Math/round$revision/1383484” rel=“noreferer”>toFixed10()

利用我来这里的一位行长,这确实涉及这里提及的所有案件。

function toFixed( num, precision ) {
    return (+(Math.round(+(num +  e  + precision)) +  e  + -precision)).toFixed(precision);
}

我将这一点用于所有财务数据,作为最佳的四舍五入功能。 你们可以对所有问题数目进行测试。 Java印允许某种精确度,因此我利用它使几乎每个数字按预期进行四舍五入。

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

In Chrome, toFixed() rounds:

859.385 ==> 859.38
859.386 ==> 859.39

见http://www.ecmascript.org/docs/tc39-2009-043.pdf。 《欧洲常规武装力量章程》第5版对<代码>至Fixed(>(第15.7.4.5节)的具体说明,我看不出它明确描述四舍五入的情况,尽管它确实描述了可能由 Chrome执行的东西。

It appears to me that if you want to control it with explicit rounding, then you should probably use the oft-suggested workaround of:

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

这将保证你们能够像你一样获得可预见的四舍五入。

Working demo here: http://jsfiddle.net/jother00/kvpgE/

由于浮点编号<>5在焦炭中不属于上半部分,因此,如果你有这样的数字,该数字将四舍五入。

859.385.toFixed(2) // results in 859.38

事实上,你可以像这里那样附上拖车点号码(零除外):

859.3851.toFixed(2) // results in 859.39

因此,开发商倾向于增加诸如<代码>0.0000001<>>代码/代码”等编号,以使之适合四舍五入,并且不会意外地改变数量的价值。

因此,我承担了增加这一数目的职能,这取决于你们有多少位数想确定你的浮动点:

    // both parameters can be string or number
    function toFixed(number, decimals) {
        const x = Math.pow(10, Number(decimals) + 2);
        return (Number(number) + (1 / x)).toFixed(decimals)
    }
    toFixed(859.385, 2) //results in 859.39
    toFixed(859.3844, 2) //results in 859.38
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)

/* returned value: (Number) 35.86 */

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.

因此,许多方案拟定语言(特别是旧的商务语言,例如COBOL)支持BCD号(统一编码的缩略语),其中每个数字自己编码为4个轨道(如没有使用A-F的超重)。

1. 价格的一般解决办法: 计算单位:%/penny和NUMBER/100。

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

您可使用<代码>Math.round()四舍五入。 如果你想四舍五入到具体小数点,你可以用几句话:

var result=Math.round(original*100)/100

如果您希望将a号作为产出,则在其他答复中考虑Math.round(

但是,如果你想获得a string,作为产出,以提交人,那么>>:code>n.to LocaleString ()比n.toFixed()更有用。

为什么? 因为它还将给许多人的头部增加mas或时间,而人类使用的是.。 例如:

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)

光谱显示,作为第一种论点,通过<代码>unfin时,用户自有地将使用(如OS所述)。 不幸的是,正如相关文件所示,Catherine利用美国当地人的情况,但今后可能符合这一期望。

我 upon不.地 upon了为什么<代码>Number.toFixed正在奇怪地行事。 我认为,土著职能是不可靠的,这是不幸的。 看看治疗方法的答案,我看看看他们中大多数* 并没有与编号<条码>35.855<>/条码”适当一致,因为T.J. Crowder对每一条都作了仔细评论。

Maybe this will answer your question.

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

regex将你的人数分成一系列的座标,例如toFixed (35.855,2):[“35.855”、“35.85”、“5”。 如果最后数(在精确截断之后)为<代码>>=5,则将<代码>Math.pow(10,-precision)添加到三毫米号。 如果您在2个小数点中重新编号,002,则将添加.01

我不知道这是否是无能为力的,因为它在浮动上仍然执行无法预测的恶性数学。 我可以说到<代码>35.855, 直至35.86/code>。

这里的Joygamdle答案应该是最好的答案,而不是这么多的黑板。

   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号更正

The only problem is the result returned is a string with thousand comma separator and so cannot be used for calculations. Using a regex i got from stack overflow to remove the comma the final result is

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

that now returns 1859.39 and can be used for calculations. The value before regex ie 1,859.39 can be used for html display while the un-formatted value 1859.39 can be used for calculations.

我知道这是一个老问题,但为什么没有这样做:

let TruncatedValueInString = ThenNumberYouWantToTruncate.toFixed(decPlaces + 1).slice(0, -1);

Note: You may only need this .toFixed() solution for handling very large numbers

Other posted solutions work well for standard numbers (below 1e21)

如果您希望操作大量和极小小小的toFixed,同时进行正确的四舍五入,无须使用图书馆和自行承担职能,那么一个可能有效的解决办法是利用BigInt,以避免因内部javascript 圆而失去准确性。

<代码>toFixed(编号,[数字])以下的功能就是这样。

仅将大量数字乘以所需的四舍五入。 数量将适当四舍五入。

这一概念是将数字分成整部分和单体部分的共同办法,但使用<条码>BigInt(<>>/代码>来持有这两个部分。 此后,在没有使用任何javascript <代码>Math或编号功能以避免准确性损失的情况下,对正数和负数进行四舍五入处理。

作为在非常特殊的情况下发放的奖金,我增加了<代码>eToNumber(<>/code>功能。 我在此张贴了。 作为一线进程这样做。 如果你想要保持短码,而不是重复这些数字,就可以删除。 [《刑法》中载有删除该文本的内容]。

我包括各种测试案例,以测试不同的可能性(其中一些是奇怪的,但确实存在)。

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

希望是有益的。

/****************************************************************************
* @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)}
All Test Cases Passed.
${"-".repeat(22)}`);

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

这样做可能有助于

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

This worked for me - "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
}

我的工作成果:

对我来说,这足以包括像助手一样的普通 j。 j)

// eslint-disable-next-line no-extend-native
Number.prototype.toFixed = function (fractionDigits) {
    var precisionTens = Math.pow(10, fractionDigits || 0);
    return (Math.round(Number(this) * precisionTens) / precisionTens);
}

这将超越本地的javascripttoFixed(原型功能。

I spent way too long on this.

export function parseFloat<TDefault>(nbr: string | number, defaultValue: TDefault): number | TDefault
export function parseFloat(nbr: string | number): number | null
export function parseFloat(nbr: string | number, defaultValue: any = null): number | null {
    if(nbr == null || nbr ===   ) return defaultValue
    const val = globalThis.parseFloat(nbr as string)
    return Number.isFinite(val) ? val : defaultValue
}

export function fullWide(n: number|string):string {
    return parseFloat(n,0).toLocaleString( en-US , {useGrouping: false, maximumFractionDigits: 20})
}

export function round(value: string | number, decimalDigits = 0): number {
    return +(`${Math.round(+(`${fullWide(value)}e${decimalDigits}`))}e${-decimalDigits}`)
}

通过所有这些测试:

test( round , () => {
    expect(round(1.2345, 0)).toBe(1)
    expect(round(1.2345, 1)).toBe(1.2)
    expect(round(1.2345, 2)).toBe(1.23)
    expect(round(1.2345, 3)).toBe(1.235)
    expect(round(1.2345, 4)).toBe(1.2345)
    expect(round(3.141592653589793, 15)).toBe(3.141592653589793)
    expect(round(3.141592653589793, 13)).toBe(3.1415926535898)
    expect(round(12.345, -1)).toBe(10)
    expect(round(4_500, -3)).toBe(5000)
    expect(round(89.684449, 2)).toBe(89.68)
    expect(round(89.685, 2)).toBe(89.69)
    expect(round(0.000000015, 8)).toBe(0.00000002)
    expect(round(1e-20, 20)).toBe(1e-20)
    expect(round(1.5e-19, 20)).toBe(0.00000000000000000015)
    expect(round(1.5e-19, 19)).toBe(0.0000000000000000002)
    expect(round( 1.5e-19 , 19)).toBe(0.0000000000000000002)
    expect(round( bacon , 19)).toBe(0)
    expect(round(100.695, 2)).toBe(100.70)
})




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签