Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中舍入错误的测试_Javascript_Jquery_Biginteger_Rounding Error - Fatal编程技术网

JavaScript中舍入错误的测试

JavaScript中舍入错误的测试,javascript,jquery,biginteger,rounding-error,Javascript,Jquery,Biginteger,Rounding Error,如何确定JavaScript中的数字是否太大(如果执行数学运算,将导致舍入错误) 例如,我有一个设置百分比格式的函数。如果它不能正确格式化传入的值,我希望它返回的值与传入的值完全相同 function formatPercent(x, decimals) { var n = parseFloat(x); // Parse (string or number) if ($.isNumeric(n) === false) { re

如何确定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%
由于格式化如此巨大的数字是一个绝无仅有的情况,我不希望这样,所以我更希望在传入数字时返回它。舍入误差开始前的限制是什么?我将如何检查它们

更新:

表示精度高达+/-9007199254740992。我正在测试,看看这是否是我需要检查的全部,以安全地失败并返回未修改的传入值

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,则使用舍入将删除小数点。如果始终以字符串形式传递
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
函数格式百分比(x,小数){
if(typeof x!=“string”&&typeof x!=“number”)返回x;
x=x+“”;//如果是数字,则转换为字符串
var r=/^(?:(\d+)(\。\d*)?|(\d*)(\。\d+)$/;//用于匹配数字字符串的RegExp
返回x.replace(r,函数(匹配,int,dec){
如果(小数>0){
int=(typeof int==“string”?int:);//如果传递的字符串没有整数
dec=(typeof dec==“string”?dec:“.”;//如果传递的字符串没有小数
而(12月长度-1分位数)
}
int=(typeof int==“string”?int:“0”);//如果传递的字符串没有整数
返回int+“%”;
});
//如果未找到匹配项,则返回格式化字符串或原始字符串转换
}
警报(formatPercent(“276403573577891842”,1));//返回276403573577891842.0%
警报(formatPercent(“276403573577891842.55”,1));//返回276403573577891842.5%
警报(formatPercent(“276403573577891842.55”,0));//返回276403573577891842%
警报(formatPercent(“.55”,1));//返回0.5%
警报(formatPercent(“.55”,0));//返回0%
警报(formatPercent(276403573577891842,1));//返回276403573577891840.0%
警报(formatPercent(“这不是一个数字”,2));//返回这不是一个数字
警报(formatPercent({key:“非数字或字符串”},2));//按原样返回对象

即使在传递数字的情况下formatPercent仍然失败,这将防止传递的字符串出现舍入错误。请注意,这并不是错误的,因为它失败的唯一情况是将过大的数字硬编码为参数。

这是我用来捕获的:

函数getSafeNumber(x){
var n=parseFloat(x);//解析并返回一个浮点数
如果($.isNumeric(n)==false | |
n>=9007199254740992 | |

n由于No的内部表示,不超过9万亿将导致这种类型的错误。这实际上取决于数字的来源,以及您打算如何处理它们。老实说,我没有看到一个应用程序涉及如此大的百分比,那么这到底是为了什么?我正在编写单元测试(QUnit)我也有类似的函数,可以格式化数字(用逗号、小数)来表示印象,点击次数可能会更大…仍然不希望像上面那样是64位整数,但在编写单元测试时,无论如何都能捕捉到它。你链接的文章确实有意义(9007199254740992)。toString(16)=“2000000000”,所以我想只需添加一个if语句,说明它是否高于或等于该值,就可以确定是否信任它的真实值。这是不正确的,因为运行代码会生成“276403573577891840%”,而不是“276403573577891842%”啊,是的,最大整数是2^53每以下。但适用于较小的浮点数。谢谢,+1,因为这确实解决了数学问题。但是,我不想在生产中使用它,因为它相当复杂,正如你在评论中提到的,不需要处理这么大的数字。但是,需要知道何时传入的值太大。我会更新确定我的问题的日期。可能想执行
=
…例如:
(9007199254740993>9007199254740992)===false
我不确定我是否理解。如果
n=9007199254740993
它将按原样返回false。将
var n=9007199254740993;n;
放入控制台并查看其内容。它将读取
9007199254740992
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
     }
 };