2015-06-10 157 views
1

我目前正在与一个JavaScript问题,我有一个应该用作过滤器的62位掩码。64位位掩码和javascript

我用了这里的代码片段,但是我不能让它在某些情况下工作。 How to do bitwise AND in javascript on variables that are longer than 32 bit?

function testBitmask(fd, filterMask){ 
          var a = fd; 
          var b = filterMask; 

          var w = 4294967296; // 2^32 

          var aHI = a/w; 
          var aLO = a % w; 
          var bHI = b/w; 
          var bLO = b % w; 

          var aAll = (aHI & bHI) * w; 
          var bAll = (aLO & bLO); 

          var retVal = (aAll + bAll) == filterMask; 
          console.log("retVal:",retVal) 
          return retVal; 
} 

我不明白为什么testBitmask(2147483648,2147483648)返回false,这就是2的31次方。 2^32 => true。 2^33 => true。

bAll会在这里变成负数,所以我假设32位整数溢出,想法?

+0

按位运算符转换的数字,以32位整数。 –

回答

0

如果在JavaScript中所有的数字都是64位浮点数,并且没有64位整数,那么不能期望以那个精度定义a和b(或者fd和filtermask),而没有舍入错误。

尝试定义封装64位整数类型的对象。

举个例子,你可以看看由Mozilla MDN作出的JS-CTYPE实现:

https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/js-ctypes_reference/Int64

,特别

https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Working_with_data#64-bit_integers

他们的Int64和UINT64对象不提供用于执行算术的任何方法,但是可以拉出高低32位部分并对其进行数学计算,然后将它们重新组合在一起。

一个简单的代码示例,使用类型化数组来代替:

bitMask = function(high = 0x0,low = 0x0) { 
    this.bm = new Uint32Array(2); 

    if (arguments.length === 0) { 
     this.bm[0] = 0x0; 
     this.bm[1] = 0x0; 
    } else if (arguments.length === 2 && typeof arguments[0] === "number" && typeof arguments[1] === "number") { 
     this.bm[0] = arguments[1]; 
     this.bm[1] = arguments[0]; 
    } 

    this.bwAND = function(filter) { 
     result = new bitMask(); 
     result.bm[0] = this.bm[0] & filter.bm[0]; 
     result.bm[1] = this.bm[1] & filter.bm[1]; 
     return result; 
    } 

    this.bwOR = function(filter) { 
     result = new bitMask(); 
     result.bm[0] = this.bm[0] | filter.bm[0]; 
     result.bm[1] = this.bm[1] | filter.bm[1]; 
     return result; 
    } 

    this.bwXOR = function(filter) { 
     result = new bitMask(); 
     result.bm[0] = this.bm[0]^filter.bm[0]; 
     result.bm[1] = this.bm[1]^filter.bm[1]; 
     return result; 
    } 

    this.bwNOT = function() { 
     result = new bitMask(); 
     result.bm[0] = ~this.bm[0]; 
     result.bm[1] = ~this.bm[1]; 
     return result; 
    } 

    this.bwEQUALS = function(b){ 
     return (this.bm[0] == b.bm[0]) && (this.bm[1] == b.bm[1]); 
    } 

    this.toString = function() { 
     var zeroes = "00000000000000000000000000000000"; 
     var strH = this.bm[1].toString(2); 
     var zerH = zeroes.substr(0,32-strH.length); 
     var strL = this.bm[0].toString(2); 
     var zerL = zeroes.substr(0,32-strL.length); 
     return zerH + strH + zerL + strL; 
    } 

} 

您可以使用它像这样:

var a = new bitMask(0x0FEDCBA9,0xFF00FF00); 
var b = new bitMask(0x12345678,0x0000FFFF); 
var c = b.bwAND(a); 
var d = b.bwOR(a); 
var e = b.bwXOR(a); 
var f = b.bwNOT(); 
var g = b.bwEQUALS(a); 

结果:

a = 0000111111101101110010111010100111111111000000001111111100000000 
    b = 0001001000110100010101100111100000000000000000001111111111111111 
a & b = 0000001000100100010000100010100000000000000000001111111100000000 
a | b = 0001111111111101110111111111100111111111000000001111111111111111 
a^b = 0001110111011001100111011101000111111111000000000000000011111111 
    ~b = 1110110111001011101010011000011111111111111111110000000000000000 
(a == b)? = false 
+0

你能给我一个代码示例吗? –