1

重複の可能性:
JavaScript の数学は壊れていますか?

ユーザーは最初の 2 つのテキスト ボックスに値を入力します。入力すると、Javascript (申し訳ありませんが、jQuery は使用できません。まだできていません) を使用して正確な合計が計算され、合計が 2 桁に丸められます。

丸め誤差が発生するのはなぜですか? また、それを修正するにはどうすればよいですか?

どうもありがとう。

うーん....パースフロート?データ型が間違っていませんか?

まるで電卓で足し算したかのような正確な答えが見たいものです。使用できる parseDecimal またはその他のデータ型はありますか?

![ここに画像の説明を入力][1]

    function SumValues() {
        //debugger;
        var txtSubsContrRbtAmt = document.getElementById("<%=txtSubsContrRbtAmt.ClientID%>");
        var txtDeMinAmt = document.getElementById("<%=txtDeMinAmt.ClientID%>");
        var txtTotRbtAmt = document.getElementById("<%=txtTotRbtAmt.ClientID%>");
        var txtRndRbtAmt = document.getElementById("<%=txtRndRbtAmt.ClientID%>");

        var total = Add(txtSubsContrRbtAmt.value, txtDeMinAmt.value);

        txtTotRbtAmt.value = total;
        txtRndRbtAmt.value = RoundToTwoDecimalPlaces(total);
    }

    function Add() {
        var sum = 0;
        for (var i = 0, j = arguments.length; i < j; i++) {
            var currentValue;
            if (isNumber(arguments[i])) {
                currentValue = parseFloat(arguments[i]);
            }
            else {
                currentValue = 0;
            }

            sum += currentValue;
        }
        return sum;
    }

    function RoundToTwoDecimalPlaces(input) {

        return Math.round(input * 100) / 100
    }

    function IsNumeric(input) {
        return (input - 0) == input && input.length > 0;
    }

    function isNumber(n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    }

  [1]: http://i.stack.imgur.com/5Otrm.png

アップデート。私はこのようなものを評価しています:

function AddWithPrecision(a, b, precision) {
        var x = Math.pow(10, precision || 2);
        return (Math.round(a * x) + Math.round(b * x)) / x;
    }
4

2 に答える 2

3

金融セクターのソフトウェア (またはお金を扱うソフトウェア) を作成する人には、絶対にフロートを使用しないという黄金律があります。したがって、お金を扱うほとんどのソフトウェアは整数のみを使用し、データ構造として 10 進数を表します。

これを行う1つの方法は次のとおりです。

(注: この関数は、数字のように見える 2 つの文字列を追加します)

(追記: わかりやすくするためにエラーチェックは行っていません。負の数も処理しません)

function addNumberStrings (a,b) {
    a = a.split('.');
    b = b.split('.');
    var a_decimal = a[1] || '0';
    var b_decimal = b[1] || '0';
    diff = a_decimal.length - b_decimal.length;
    while (diff > 0) {
        b_decimal += '0';
        diff --;
    }
    while (diff < 0) {
        a_decimal += '0';
        diff ++;
    }
    var decimal_position = a_decimal.length;

    a = a[0] + a_decimal;
    b = b[0] + b_decimal;

    var result = (parseInt(a,10)+parseInt(b,10)) + '';

    if (result.length < decimal_position) {
        for (var x=result.length;x<decimal_position;x++) {
            result = '0'+result;
        }
        result = '0.'+result
    }
    else {
        p = result.length-decimal_position;
        result = result.substring(0,p)+'.'+result.substring(p);
    }
    return result;
}

*注: コードは単純化されており、追加機能は宿題として省略されています。

于 2012-08-02T04:39:20.523 に答える
0

追加を希望どおりに修正するには、各数値の小数点以下の桁数を何らかの方法でカウントすることをお勧めします。たとえば、このメソッドでは、最大値を toFixed に渡し、残りのゼロをトリミングします。

function AddTwo(n1, n2) {
    var n3 = parseFloat(n1) + parseFloat(n2);
    var count1 = Decimals(n1, '.');
    var count2 = Decimals(n2, '.');
    var decimals = Math.max(count1, count2);
    var result = n3.toFixed(decimals)
    var resultDecimals = Decimals(result, '.');
    if (resultDecimals > 0) {
        return result.replace(/\.?0*$/,'');
    }
    else {
        return result;
    }
}

// Included for reference - I didn't write this
function Decimals(x, dec_sep)
{
    var tmp=new String();
    tmp=x;
    if (tmp.indexOf(dec_sep)>-1)
        return tmp.length-tmp.indexOf(dec_sep)-1;
    else
        return 0;
} 

これがそのJSFiddleです

于 2012-08-02T03:55:04.727 に答える