2015-06-10 191 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

你能給我一個代碼示例嗎? –