75

一部のチェックボックスにバインドするために JavaScript を使用していますが、toFixed(2)切り上げられません。丸められない理由はありますか?たとえば、数字が の場合、の代わりに859.385表示されるだけです。859.38859.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

24

これを、すべての財務データで最適な丸め関数として使用するために作成しました。問題のあるすべての番号でテストできます。Javascript はある程度の精度を許容するので、ほぼすべての数値を期待どおりに丸めるために 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 に答える
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 に答える
6

を使用しMath.round()て数値を丸めることができます。特定の小数点に丸めたい場合は、ちょっとした計算を使用できます。

var result=Math.round(original*100)/100
于 2012-04-04T16:13:57.400 に答える
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

ここでの喜びの絡みの答えは、非常に多くのハックアラウンドではなく、最良の答えであるはずです.

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

1859.39 ではなく 1859.38 など、誤った丸めを行います

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

1,859.39 を正しく丸める

唯一の問題は、返される結果が 3 桁のカンマ区切りの文字列であるため、計算に使用できないことです。スタックオーバーフローから取得した正規表現を使用してコンマを削除すると、最終結果は次のようになります

 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 に答える
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 に答える
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 に答える
0

これは私にとってはうまくいきました-「ハック」

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 に答える