# Bitwise Math and Masking Functions

Monday Apr 21st 2008 by DatabaseJournal.com Staff
Share:

This script performs bitwise math and masking operations on numbers.

>>Script Language and Platform: Oracle
This script performs bitwise math and masking operations on numbers. Performs the bitwise operations "AND", "OR", "XOR" and "NOT"; Turns a mask of bits ON or OFF in a larger array of bits; Tests whether a number is a "single bit" number; Tests whether a mask of bits is ON in a larger array of bits.

Author: Michael Donnelly

--
-- This script is (c) 2004 Michael V. Donnelly
--
CREATE OR REPLACE PACKAGE bitwise
IS
-- This function is the same as the Oracle SQL Function BITAND
-- Example:
--
-- BIT_AND(4,8) = 0
--
FUNCTION BIT_AND
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER DETERMINISTIC;
-- This function implements the bitwise OR function
-- Example:
--
-- BIT_OR(4,8) = 12
--
FUNCTION BIT_OR
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER DETERMINISTIC;
-- This function implements the bitwise XOR function
-- Example:
--
-- BIT_XOR(2,6) = 4
--
FUNCTION BIT_XOR
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER DETERMINISTIC;
-- This function ensures that the bit(s) in param2 are "On" in
-- param1, regardless of whether they were on or off to begin
-- with. This is equivalent to the bit_or() function, but
-- is included because it is conceptually distinct.
FUNCTION TURN_BITS_ON
( bitarray IN NUMBER,
RETURN NUMBER DETERMINISTIC;
-- This function ensures that the bit(s) in param2 are "Off" in
-- param1, regardless of whether they were on or off to begin
-- with. This is equivalent to performing a bit_or to ensure
-- that the bits are "On" and then performing a bit_xor on the
-- result, to ensure that the bits are now off.
FUNCTION TURN_BITS_OFF
( bitarray IN NUMBER,
RETURN NUMBER DETERMINISTIC;
-- This function implements the bitwise NOT function
-- 'length' indicates the size of a bit array.
-- Example:
--
-- length = 4
-- array = 1111 (15)
-- BIT_NOT(2,4) = BIT_XOR(2,15)
--
-- If the length of the array represented by 'length'
-- contains fewer binary positions than the array
-- represented by 'param1', the NOT will be performed
-- against an array of the same length as 'param1'
-- Example:
--
-- length = 2
-- array = 11 (3)
-- param1 = 8 (0001)
-- BIT_NOT(8,2) = BIT_XOR(8,15)
--
FUNCTION BIT_NOT
( param1 IN NUMBER,
length IN NUMBER)
RETURN NUMBER DETERMINISTIC;
-- This function determines whether 'param' is an exponent of 2
-- It retuns 'Y' if a single bit is set in the number,
-- 'N' if more than one bit.
-- Example:
--
-- IS_BIT(4) (Y)
-- IS_BIT(6) (N)
FUNCTION IS_BIT
( param IN NUMBER)
RETURN CHAR DETERMINISTIC;
-- This function determines whether the bit 'mask' is set in
-- the number 'bitarray'
-- If the bit is set, 'Y' is returned. If not, 'N' is returned.
-- Example:
--
-- 10 = 0101
( bitarray IN NUMBER,
RETURN CHAR DETERMINISTIC;
END;
/
CREATE OR REPLACE PACKAGE BODY bitwise
IS
FUNCTION BIT_AND
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN BITAND(param1,param2);
END BIT_AND;

FUNCTION BIT_OR
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN ((param1 + param2) - BITAND(param1,param2));
END BIT_OR;
FUNCTION BIT_XOR
( param1 IN NUMBER,
param2 IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN ((param1 + param2) - (2 * BITAND(param1,param2)));
END BIT_XOR;
FUNCTION BIT_NOT
( param1 IN NUMBER,
length IN NUMBER)
RETURN NUMBER IS
cur_len NUMBER;
i NUMBER;
param2 NUMBER;
ret_val NUMBER;
BEGIN
param2 := 0;
cur_len := length - 1;
i := 0;
WHILE cur_len > -1 LOOP
param2 := param2 + POWER(2,cur_len);
cur_len := cur_len - 1;
END LOOP;
WHILE param2 < param1 LOOP
param2 := param2 + POWER(2,length + i);
i := i + 1;
END LOOP;
RETURN ((param1 + param2) - (2 * BITAND(param1,param2)));
END BIT_NOT;
FUNCTION TURN_BITS_ON
( bitarray IN NUMBER,
RETURN NUMBER IS
BEGIN
END TURN_BITS_ON;
FUNCTION TURN_BITS_OFF
( bitarray IN NUMBER,
RETURN NUMBER IS
BEGIN
RETURN BITWISE.bit_xor(
);
END TURN_BITS_OFF;
FUNCTION IS_BIT
( param IN NUMBER)
RETURN CHAR IS
cur_val NUMBER;
test_val NUMBER;
loop_ct NUMBER;
ret_val CHAR;
BEGIN
cur_val := ABS(param);
IF cur_val = 1 OR cur_val = 0 THEN
RETURN 'Y';
END IF;
RETURN 'N';
END IF;
-- cur_val is a positive multiple of 2.
loop_ct := 0;
test_val := 0;
WHILE test_val <= cur_val LOOP
test_val := POWER(2,loop_ct);
loop_ct := loop_ct + 1;
IF test_val = cur_val THEN
RETURN 'Y';
END IF;
END LOOP;
RETURN 'N';
RETURN ret_val;
END IS_BIT;
( bitarray IN NUMBER,
RETURN CHAR
IS
ret_val CHAR;
BEGIN
ret_val := 'Y';
ELSE
ret_val := 'N';
END IF;
RETURN ret_val;