本来遇到的问题是如何在Javascript中将十进制转变为十六进制(http://segmentfault.com/q/10100000000...)
第一次回答时我使用了这种方案:
var dec2hex = function(dec) { var buf = [], map = '0123456789ABCDEF'; while (parseInt(dec / 16, 10) !== 0) { buf.unshift(map[dec % 16]); dec = parseInt(dec / 16, 10); } buf.unshift(map[dec % 16]); return buf.join(''); };
而在另一个我提出的问题中(http://segmentfault.com/q/10100000001...),我突然意识到还可以通过另一种方式进行转换:
var dec2hex2 = function(dec) { var hex = [], HEX = '0123456789ABCDEF'; do { hex.unshift(HEX[dec & 0xF]); } while ( (dec = dec >> 4) !== 0 ); return hex.join(''); };
知道最后google,我才发现原来事实比我想象的要简单得多。
var dec2hex3 = function(dec) { return dec.toString(16); };
然而,问题来了。
第一次测试
输入:
var num = 542352345; console.log(dec2hex(num)); console.log(dec2hex3(num)); console.log(dec2hex2(num));
输出:
2053A3D9 2053a3d9 2053A3D9
一切正常。
第二次测试
输入:
var num = 34542352345; console.log(dec2hex(num)); console.log(dec2hex3(num)); console.log(dec2hex2(num));
输出:
80AE277D9 80ae277d9 AE277D9
Seemed weird?
第三次测试
输入:
var num = 5234542352345; console.log(dec2hex(num)); console.log(dec2hex3(num)); console.log(dec2hex2(num));
输出:
4C2C30997D9 4c2c30997d9
这时候,dec2hex2函数似乎一直在运行,没有结果输出。
事先声明上述数字纯粹是我瞎打的。这时候我的第一个反应,是不是因为数字已经超过了32位(因为我的机器是32位的),然而我做了另外一个实验。
输入:
var num = parseInt(0xFFFFFFFF, 16); console.log(dec2hex(num)); console.log(dec2hex3(num)); console.log(dec2hex2(num));
输出:
4294967295 4294967295
此时发生了和第三次测试同样的情况。
请问这是怎么回事呢?是不是发生了数字的溢出?那么如何避免和处理呢?
关键在于dec2hex2里用到的位移运算符。在ECMA规范中,位运算符总是针对32bit的整数进行的操作。至于死循环,是因为位移的时候会保留符号位。那个数字的bit32正好是1,所以一直右移最后得到的总是0xFFFFFFFF。
Ref: http://stackoverflow.com/questions/23...
p.s. 建议,除非必要,避免使用位移运算符。你能想到的简单优化,编译器也很容易做到。