0

JavaScript で数値が大きすぎる (計算を実行すると丸め誤差が発生する) かどうかを判断するにはどうすればよいですか。

たとえば、パーセンテージをフォーマットする関数があります。渡された値を正しくフォーマットできない場合は、渡されたとおりの値を返すようにします。

function formatPercent(x, decimals) {
     var n = parseFloat(x);                 // Parse (string or number)
     if ($.isNumeric(n) === false) {
         return x;                          // Return original if not a number
     } else {
         return n.toFixed(decimals) + '%';  // Return formatted string
     }
 };

alert(formatPercent(276403573577891842, 2)); // returns 276403573577891840.00%

このような巨大な数値をフォーマットすることはまれなケースであり、予期されていないため、渡された数値をそのまま返すことをお勧めします。丸めエラーが発生する前の制限と、それらを確認するにはどうすればよいですか?

アップデート:

Number が精度を失うことなく到達できる JavaScript の最大の整数値は? 精度は +/- 9007199254740992 まで機能します。安全に失敗し、渡された値を変更せずに返すためにチェックする必要があるのはそれだけかどうかをテストしています。

4

4 に答える 4

1

常に文字列として渡すxと、丸めエラーが発生しなくなります。問題は276403573577891842、数値リテラルが解析されるときに右に丸められることですが、文字列を使用する場合、それは決して起こりません。これを試してください:

function formatPercent(x, decimals) {
    if(typeof x != "string" && typeof x != "number") return x;
    x = x+"";//convert to string if it is a number
    var r = /^(?:(\d+)(\.\d*)?|(\d*)(\.\d+))$/;// RegExp for matching numerical strings
    return x.replace(r, function(match, int, dec){
        if(decimals>0){
            int = (typeof int == "string"?int:"");//if passed string didn't have integers
            dec = (typeof dec == "string"?dec:".");//if passed string didn't have decimals
            while(dec.length-1<decimals) dec += "0";//pad zeroes until dec.length-1==decimals
            return int+dec.slice(0,decimals+1)+"%";//in case dec.length-1>decimals
        }
        int = (typeof int == "string"?int:"0");//if passed string didn't have integers
        return int+"%";
    });
    // Return formatted string or original string conversion if no match found
}

alert(formatPercent("276403573577891842", 1));// returns 276403573577891842.0%
alert(formatPercent("276403573577891842.55", 1));// returns 276403573577891842.5%
alert(formatPercent("276403573577891842.55", 0));// returns 276403573577891842%
alert(formatPercent(".55", 1));//returns .5%
alert(formatPercent(".55", 0));//returns 0%
alert(formatPercent(276403573577891842, 1));// returns 276403573577891840.0%
alert(formatPercent("this is not a number", 2));// returns this is not a number
alert(formatPercent({key:"not number or string"}, 2));// returns the object as it was

数値を渡す場合は formatPercent が引き続き失敗しますが、これにより、渡された文字列の丸めエラーが防止されます。失敗する唯一のケースは、大きすぎる数値がパラメーターとしてハードコーディングされている場合であるため、これは誤りではないことに注意してください。

于 2013-07-19T20:56:29.183 に答える
0

これは、大きすぎるまたは小さすぎる整数をキャッチするために使用したものです。

function getSafeNumber(x) {
     var n = parseFloat(x);    // Parse and return a floating point number
     if ($.isNumeric(n) === false || 
         n >= 9007199254740992 || 
         n <= -9007199254740992) {
         return false;         // Not numeric or too big or too small
     } else {
         return n;             // return as number
     }
 };
于 2013-07-19T22:09:52.160 に答える
0
function formatPercent(x, decimals) {
     var n = parseFloat(x);                 // Parse (string or number)
     if ($.isNumeric(n) === false) {
         return x;                          // Return original if not a number
     } else {
         var d = Math.pow(10, decimals)
         return (Math.round(n * d) / d).toString() + "%";
      }
 };

丸めを使用すると、.00 の場合は小数点が削除されます

于 2013-07-19T19:56:03.470 に答える
-1

内部表現 no

于 2014-07-11T19:17:48.653 に答える