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%

由于格式化如此巨大的数字是一种极端情况并且不是预期的,我宁愿只返回传入的数字。舍入错误开始之前的限制是什么,我将如何检查它们?

更新:

一个数字可以在不损失精度的情况下达到 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 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 回答
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 回答
-1

不超过九亿会导致这种类型的错误,因为内部表示没有

于 2014-07-11T19:17:48.653 回答