- Joined
- Nov 7, 2014
- Messages
- 571
Bitops is a fork of the Binary library by d07.RiV.
The Binary library implemented the functions NOT, SHL, SHR, AND, OR, XOR for integers wihch did not have their signed bit set.
This library implements the functions as if their arguments are unsigned 32-bit integers (Jass2 has only signed 32-bit integers), it also adds the pow2 and log2 functions.
The Binary library implemented the functions NOT, SHL, SHR, AND, OR, XOR for integers wihch did not have their signed bit set.
This library implements the functions as if their arguments are unsigned 32-bit integers (Jass2 has only signed 32-bit integers), it also adds the pow2 and log2 functions.
JASS:
library Bitops initializer bitops_init
//! novjass
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
// bitwise not
function NOT takes integer a returns integer
// left shift (a << b)
function SHL takes integer a, integer b returns integer
// zero-fill right shift (a >>> b)
function SHR takes integer a, integer b returns integer
// NOTE: there is no sign-propagating right shift (arithmetic right shift) function
// bitwise AND
function AND takes integer a, integer b returns integer
// bitwise OR
function OR takes integer a, integer b returns integer
// bitwise XOR
function XOR takes integer a, integer b returns integer
// 2^x, x: 0 <= x <= 31
function pow2 takes integer x returns integer
// base 2 logarithm, e.g: log2(256) == 8 because 2^8 = 256
// NOTE: expects only numbers which are powers of two
function log2 takes integer x returns integer
// NOTE: binary operations use lookup tables for 4-bit blocks
//! endnovjass
globals
// Offsets:
// 0x000 = powers of 2 (up to 32)
// 0x100 = AND
// 0x200 = OR
// 0x300 = XOR
//
private integer array bintable
private integer array log2_table
endglobals
function NOT takes integer a returns integer
return -1 - a
endfunction
function SHL takes integer a, integer b returns integer
return a * bintable[b]
endfunction
function SHR takes integer a, integer b returns integer
if a >= 0 then
return a / bintable[b]
else
// set a = a + 0x80000000
// set a = a / bintable[b]
// set a = a + bintable[31 - b]
// return a
return (a + 0x80000000) / bintable[b] + bintable[31 - b]
endif
endfunction
private function SAND takes integer a, integer b returns integer
local integer ta = a / 16
local integer tb = b / 16
local integer x = bintable[0x100 + (a - ta * 16) + (b - tb * 16) * 16]
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x100 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00000010
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x100 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00000100
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x100 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00001000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x100 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00010000
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x100 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00100000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x100 + (a - ta * 16) + (b - tb * 16) * 16] * 0x01000000
set a = ta / 16
set b = tb / 16
return x + bintable[0x100 + (ta - a * 16) + (tb - b * 16) * 16] * 0x10000000
endfunction
function AND takes integer a, integer b returns integer
if a >= 0 and b >= 0 then
return SAND(a, b)
elseif a < 0 and b < 0 then
return SAND(a + 0x80000000, b + 0x80000000) + 0x80000000
else
if a < 0 then
set a = a + 0x80000000
elseif b < 0 then
set b = b + 0x80000000
endif
return SAND(a, b)
endif
endfunction
private function SOR takes integer a, integer b returns integer
local integer ta = a / 16
local integer tb = b / 16
local integer x = bintable[0x200 + (a - ta * 16) + (b - tb * 16) * 16]
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x200 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00000010
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x200 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00000100
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x200 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00001000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x200 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00010000
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x200 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00100000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x200 + (a - ta * 16) + (b - tb * 16) * 16] * 0x01000000
set a = ta / 16
set b = tb / 16
return x + bintable[0x200 + (ta - a * 16) + (tb - b * 16) * 16] * 0x10000000
endfunction
function OR takes integer a, integer b returns integer
if a >= 0 and b >= 0 then
return SOR(a, b)
else
if a < 0 then
set a = a + 0x80000000
endif
if b < 0 then
set b = b + 0x80000000
endif
return SOR(a, b) + 0x80000000
endif
endfunction
private function SXOR takes integer a, integer b returns integer
local integer ta = a / 16
local integer tb = b / 16
local integer x = bintable[0x300 + (a - ta * 16) + (b - tb * 16) * 16]
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x300 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00000010
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x300 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00000100
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x300 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00001000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x300 + (a - ta * 16) + (b - tb * 16) * 16] * 0x00010000
set a = ta / 16
set b = tb / 16
set x = x + bintable[0x300 + (ta - a * 16) + (tb - b * 16) * 16] * 0x00100000
set ta = a / 16
set tb = b / 16
set x = x + bintable[0x300 + (a - ta * 16) + (b - tb * 16) * 16] * 0x01000000
set a = ta / 16
set b = tb / 16
return x + bintable[0x300 + (ta - a * 16) + (tb - b * 16) * 16] * 0x10000000
endfunction
function XOR takes integer a, integer b returns integer
if a >= 0 and b >= 0 then
return SXOR(a, b)
elseif a < 0 and b < 0 then
return SXOR(a + 0x80000000, b + 0x80000000)
elseif a < 0 then
return SXOR(a + 0x80000000, b) + 0x80000000
else // if b < 0 then
return SXOR(a, b + 0x80000000) + 0x80000000
endif
endfunction
function pow2 takes integer x returns integer
return bintable[x]
endfunction
function log2 takes integer x returns integer
if x < 0 then
return 31
endif
if x < 0x00002000 then
return log2_table[x]
endif
set x = x / 0x00002000
if x < 0x00002000 then
return 13 + log2_table[x]
endif
set x = x / 0x00002000
return 26 + log2_table[x]
endfunction
private function bitops_init takes nothing returns nothing
local integer i
local integer a
local integer b
local integer ta
local integer tb
set bintable[0] = 1
set i = 1
loop
exitwhen i > 31
set bintable[i] = 2 * bintable[i - 1]
set i = i + 1
endloop
set i = 0
loop
exitwhen i >= 256
set a = i / 16
set b = i - a * 16
set ta = a - (a / 2) * 2
set tb = b - (b / 2) * 2
set bintable[0x100 + i] = ta * tb
set bintable[0x200 + i] = ta + tb - ta * tb
set bintable[0x300 + i] = ta + tb - 2 * ta * tb
set a = a / 2
set b = b / 2
set ta = a - (a / 2) * 2
set tb = b - (b / 2) * 2
set bintable[0x100 + i] = bintable[0x100 + i] + 2 * (ta * tb)
set bintable[0x200 + i] = bintable[0x200 + i] + 2 * (ta + tb - ta * tb)
set bintable[0x300 + i] = bintable[0x300 + i] + 2 * (ta + tb - 2 * ta * tb)
set a = a / 2
set b = b / 2
set ta = a - (a / 2) * 2
set tb = b - (b / 2) * 2
set bintable[0x100 + i] = bintable[0x100 + i] + 4 * (ta * tb)
set bintable[0x200 + i] = bintable[0x200 + i] + 4 * (ta + tb - ta * tb)
set bintable[0x300 + i] = bintable[0x300 + i] + 4 * (ta + tb - 2 * ta * tb)
set ta = a / 2
set tb = b / 2
set bintable[0x100 + i] = bintable[0x100 + i] + 8 * (ta * tb)
set bintable[0x200 + i] = bintable[0x200 + i] + 8 * (ta + tb - ta * tb)
set bintable[0x300 + i] = bintable[0x300 + i] + 8 * (ta + tb - 2 * ta * tb)
set i = i + 1
endloop
set log2_table[4096] = 12
set log2_table[2048] = 11
set log2_table[1024] = 10
set log2_table[512] = 9
set log2_table[256] = 8
set log2_table[128] = 7
set log2_table[64] = 6
set log2_table[32] = 5
set log2_table[16] = 4
set log2_table[8] = 3
set log2_table[4] = 2
set log2_table[2] = 1
set log2_table[1] = 0
endfunction
endlibrary
Last edited: