如何在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%
由于格式化这么大的数字是一个极端情况并且没有预期,我宁愿只返回传入的数字。舍入错误开始之前的限制是多少?我将如何检查它们? / p>
更新:
What is JavaScript's highest integer value that a Number can go to without losing precision?表示精度最高可达+/- 9007199254740992.我正在测试是否需要检查以确保安全失败并返回未修改的传入值。
答案 0 :(得分: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在传递数字的情况下仍然失败,这将防止传递字符串的舍入错误。请注意这不是不正确的,因为它失败的唯一情况是当一个太大的数字被硬编码为参数时。
答案 1 :(得分: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
,使用舍入将丢弃小数答案 2 :(得分:0)
这是我过去常常捕捉的too big or too small integers:
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
}
};
答案 3 :(得分:-1)
由于no
的内部表示,不超过9个quardbillion将导致此类错误