parseInt 小陷阱

看代码:

alert(parseInt(0.000001));alert(parseInt(0.0000001));

第一条语句输出 0, 第二条语句输出 1, 囧。

继续看代码:

alert(parseInt('0.000001'));alert(parseInt('0.0000001'));

都输出 0, 这才符合预期。

查看 ECMA-262 规范,parseInt 会先调用 toString 方法。问题已逐渐清晰:

alert(0.000001);alert(0.0000001);

第一条语句原样输出,第二条语句输出 1e-7.
继续翻查 ECMA-262 9.8.1 ToString Applied to the Number Type 一节,恍然大悟:
assertEquals("0.00001", (0.00001).toString());
assertEquals("0.000001", (0.000001).toString());
assertEquals("1e-7", (0.0000001).toString());
assertEquals("1.2e-7", (0.00000012).toString());
assertEquals("1.23e-7", (0.000000123).toString());
assertEquals("1e-8", (0.00000001).toString());
assertEquals("1.2e-8", (0.000000012).toString());
上面是 V8 引擎 number-tostring 的单元测试脚本, 很好地诠释了 ECMA 规范。
小结:对于小于 1e-6 的数值来说,ToString 时会自动转换为科学计数法。因此 parseInt 方法,在参数类型不确定时,最好封装一层:
function parseInt2(a) {
    if(typeof a === 'number') {
        return Math.floor(a);
    }
    return parseInt(a);
}
Safari似乎没有先toString,执行javascript:void(alert(parseInt(0.0000001))) 输出的是 0。如果就是浮点数转整数最好用位运算符,还快.
用这些内置函数,反而不易掌握.alert(0|0.0000001)
白菜的弟弟的同学的老师的儿子的妈妈养的小狗的表弟的主人的朋友说看帖不回会被鄙视de

添加新评论 »

【f(x,y)=(y^2-4y)(x^2-6x)的极值(请填入答案,答案见本表单title)】