这个问题是已经毕业的学员李佳问到的,本想在网上查一下给他个答案省事.转念一想,如果网上如果他能在网上查到看的明白的方案应该不至于来问我.索性自己给他解一解.因为貌似这个问题还是有点意思的.
首先,要知道为什么这个问题会成为一个问题.这里就不得不说说JS当中坑爹的位运算规则.
我们知道JS是一种弱类型的脚本语言,所有的数值无论是整数还是小数,其实都是按照64为位的浮点形式存储.然而当两个整数在进行位运算时,却又会自动转化为32位的有符号整数.这才导致了这个蛋疼的问题.
解决这个问题以前我们先来考虑这样一件事情,如果在你面前有一缸水,但是你只有一个32L的桶,现在你想取50L水,要怎样取. 跑两趟,对吗?两趟不行,三趟种可以吧.
计算机是为人类服务的,这种思路一定可以行的通.
比如现在有一个超级大的数,我们假定它是0xf ffff ffff,好了九个F够了,超过32位的就行.如果我们要拿着这个数跟0xf000 000f异或.我们希望得到的结果是0x f 0fff fff0对吗? 可是理想很丰满,现实却是残酷的,因为当你直接拿这两个数异或之后,发现结果是 0x 0fff fff0, 因为转化为32位的整数时,那个超标的数的高字节部分被截掉了,坑爹啊?
回顾我刚才讲到的分趟原理, 既然JS每次最多只能处理32位的位运算,那么能不能分段来处理呢?很肯定的告诉你,可以.
那么接下来的问题就是:
1,分几段,怎么分
2,分出来的数据如何处理
3,分段处理的数据如何整合
结合上面的数据来分析,0xf ffff ffff总有效的数据实际上只存在于后面的9个字节中,而JS的位运算最多可以处理4个字节的数据,只需要将一个字节抽离出来单独处理,剩下的部分作为另一段处理即可.
浏览器有问题,已保存就崩,直接丢代码了
var longN = 0xfffffffff;
var shortN = 0x0ffffff0;
var tool = 0x000000ff;
var t_long = longN & tool;
var t_short = shortN & tool;
var t_r = t_long ^ t_short;
var offset = Math.pow(2,tool.toString(16).length * 4);
longN = Math.floor(longN / offset);
shortN = Math.floor(shortN / offset);
var t_h = longN ^ shortN;
t_h *= offset;
var result = t_h + t_r
console.log(result.toString(16));
上面的代码只是一个例子,体现的是一种思路,但还不是一个完整健壮的解决方案,因为更多位的数上面这个是无法实现的,而且因为32的数是有符号的,所以在分两段处理时,其中一段最大只能到31位,所以最稳妥的方法应该是根据两个操作数中长度最大的数据灵活拆分. todo……
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)