当我尝试“eval”函数作为eval(“020 * 05 + 05”)时,它返回85而不是105。 有人可以解释为什么eval函数的行为如下吗?还建议任何人来解决这个问题。
答案 0 :(得分:7)
以零开头的数字常量(如“020”)被解释为八进制。这对于C,C ++,Java,Javascript以及大多数其他语言都是如此,即使与C有着模糊的美化关系。
如果出于某种原因,你确实需要使用“eval()”,并且你在数字常量上有这些奇怪的字符串,假冒前导零,你可能会尝试这样的事情:
var answer = eval(weirdString.replace(/\b0(\d+)\b/g, '$1'));
但是我希望你能找到一种方法来使用“eval()”。 (请注意下面的注释,注意上面显示的hack会出现包含小数部分的数字的问题。)
答案 1 :(得分:2)
Javascript将以0开头的数字视为八进制。您可以删除前导0或使用parseInt(yourNumber,10)转换为基数10.
答案 2 :(得分:2)
这是一个描述ParseInt函数如何在JavaScript中工作的链接,因此也是您获得意外结果的原因。
答案 3 :(得分:1)
假设您首先确保表达式中没有任何非法字符(尤其是小写的z字符),这是一个更干净,更安全的答案:
"blah blah arithmetic with leading 0's... 0012.0034 + 1200 - 05.0600*0 + 0"
.replace(/\b0+\b/g, 'z') // replace bare zeros with sentinel
.replace(/[1-9\.]0+/g, m => m.replace(/0/g, 'z')) // save these too
.replace(/0/g, '') // throw away the rest of the zeros
.replace(/z/g, '0') // turn sentinels back to zeros
HT Adam Wolf让我想起了sentinel一词。
答案 4 :(得分:0)
“100. 0001 ”。替换(/ \ b0(\ d +)\ b / g,'$ 1')=“100。 1 ”所以它很危险溶液
我的解决方案:
function $calc(n, round, min, max) {
/// <summary>calculate expression from string</summary>
/// <param name="round" type="int">optional</param>
/// <param name="min" type="int">optional. minimum allowed value. if less return 0</param>
/// <param name="max" type="int">optional. maximum allowed value. if more return 0</param>
if (!n) return 0;
try {
n = Number(eval(n
.replace(/[^\d\.\-\+\*\/\(\)\e]/g, '')//remove illegal symbols
.replace(/^0+/, '')//replace first leading zero
.replace(/[^\d\.]+0+/g, function (s) {return s.substr(0, 1);}) //replace leading zero
));
} catch (e) { return 0; }
if (n == 0 || !isFinite(n)) return 0;
if (round != undefined) { var t = Math.pow(10, round); n = Math.round(n * t) / t; }
if (min != undefined && n < min) return 0;
if (max != undefined && n > max) return 0;
return n;
}
功能安全。如果计算失败或NaN为无穷大,则返回0
$calc('0100.08-(0.01+00.04)')=100.03
$calc('0/0')=0 //NaN
$calc('1/3',2)=0.33 //round