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);
}

May 22nd, 2010 on 13:37
昨天还和崇厚讨论这个来着。而且发现Safari似乎没有线toString,执行javascript:void(alert(parseInt(0.0000001))) 输出的是 0。
May 22nd, 2010 on 13:44
@陈成:的确如此,Safari 威武。
May 24th, 2010 on 8:30
强,这种问题都能发现。也可以用下面方法解决:
parseInt((0.000000001).toString(8), 8)
May 24th, 2010 on 8:30
?怎么出了个表情,
parseInt((0.000000001).toString(8),8)
May 24th, 2010 on 9:17
这个以前还真是没有注意过~~~
May 24th, 2010 on 10:03
如果就是浮点数转整数最好用位运算符,还快.
用这些内置函数,反而不易掌握.
alert(0|0.0000001)
May 24th, 2010 on 10:06
确实是值得注意的一点!!
May 24th, 2010 on 10:46
这算不算是 JavaScript的bug 0 0
May 25th, 2010 on 9:23
同意“不及格的程序员-八神”,如果能确保输入是纯数字的话,用位运算会更简便,比如:
alert(~~0.0000001)
May 25th, 2010 on 17:01
玉伯大哥 我是普通pc 不是mac
用什么编辑器开发前端最好 我用dw感觉效率不高
看外国教程用的textmate 怎么样
May 26th, 2010 on 12:40
@lifesinger: 问个与主题无关的话题,
DOM.addStyleSheet(style, STYLE_ID); // style为css字符串
YUI内部是如何实现这个的?IE下
May 26th, 2010 on 13:34
alert(~~0.0000001)
晕了..什么意思..
May 26th, 2010 on 15:03
@lifesinger:打扰了,问题已经解决了 呵呵。
June 2nd, 2010 on 9:07
感觉还是很不错.
向楼主学习!
June 7th, 2010 on 12:01
想请教一个问题:
如下方式是可以获得结果,
(function(){
var fp = foo.prototype;
console.log(“______________fp:”+fp.toSource()); //result:______________fp:({})
function foo(){};
})();
但是如下方式却是得不到结果,
var fp = foo.prototype;
console.log(“______________fp:”+fp.toSource());//ReferenceError.foo is not defined
function foo(){};
请问:这如何解释??
June 9th, 2010 on 10:13
楼主还真够细心的,一年多没有再写代码了,都快忘了,回味一下 唉
June 11th, 2010 on 10:15
关注你了
团美网受益匪浅啊
继续更新哦!通过订阅功能不错,很好了
June 22nd, 2010 on 18:53
alert(0|0.0000001)
alert(~~0.0000001)
很巧妙,但位运算要留意32位溢出
当operand值比较大时,用parseInt((0.000000001).toString( ), 10) 会保险一些
to vapour: 我明白parseInt的base参数必不可少,但toString函数的base参数是不是必要的?诚心请教
javascript的位运算用得少,不过《heigh performance javascript》里说位运算高效;但《javascript: the good part》里却说位运算前需要转换,因此低效。不知道到底谁说的对。
June 23rd, 2010 on 9:50
补充一下,我真笨,能用位运算的话,必定operand是浮点数的前提成立了,那就用Math.floor好了,干嘛要parseInt呢,敲头
leave a reply