Skip to content

Instantly share code, notes, and snippets.

@allfro
Last active June 17, 2024 13:41
Show Gist options
  • Save allfro/d93cbc6980f38cf309555eff77381ced to your computer and use it in GitHub Desktop.
Save allfro/d93cbc6980f38cf309555eff77381ced to your computer and use it in GitHub Desktop.
-- implementation of bitwise & operator for the numeric data type
create or replace function numeric_and(leftarg numeric, rightarg numeric) returns numeric as
$$
declare
width int := 32;
modulo bigint := 2 ^ width;
b1 bigint := 0;
b2 bigint := 0;
r numeric := 0;
i integer := 0;
begin
while leftarg != 0 and rightarg != 0
loop
b1 := leftarg % modulo;
b2 := rightarg % modulo;
r := r + ((b1 & b2)::numeric << (width * i));
leftarg = leftarg >> width;
rightarg = rightarg >> width;
i := i + 1;
end loop;
return r;
end;
$$ language plpgsql;
create operator & (
function = numeric_and,
leftarg = numeric,
rightarg = numeric
);
-- implementation of bitwise | operator for the numeric data type
create or replace function numeric_or(leftarg numeric, rightarg numeric) returns numeric as
$$
declare
width int := 32;
modulo bigint := 2 ^ width;
b1 bigint := 0;
b2 bigint := 0;
r numeric := 0;
i integer := 0;
begin
while leftarg != 0 or rightarg != 0
loop
b1 := leftarg % modulo;
b2 := rightarg % modulo;
r := r + ((b1 | b2)::numeric << (width * i));
leftarg = leftarg >> width;
rightarg = rightarg >> width;
i := i + 1;
end loop;
return r;
end;
$$ language plpgsql;
create operator | (
function = numeric_or,
leftarg = numeric,
rightarg = numeric
);
-- implementation of bitwise # operator for the numeric data type
create or replace function numeric_xor(leftarg numeric, rightarg numeric) returns numeric as
$$
declare
width int := 32;
modulo bigint := 2 ^ width;
b1 bigint := 0;
b2 bigint := 0;
r numeric := 0;
i integer := 0;
begin
while leftarg != 0 or rightarg != 0
loop
b1 := leftarg % modulo;
b2 := rightarg % modulo;
r := r + ((b1 # b2)::numeric << (width * i));
leftarg = leftarg >> width;
rightarg = rightarg >> width;
i := i + 1;
end loop;
return r;
end;
$$ language plpgsql;
create operator # (
function = numeric_xor,
leftarg = numeric,
rightarg = numeric
);
-- implementation of bitwise >> operator for the numeric data type
create or replace function numeric_shift_right(leftarg numeric, rightarg numeric) returns numeric as
$$
begin
return floor(leftarg / (2 ^ rightarg));
end;
$$ language plpgsql;
create operator >> (
function = numeric_shift_right,
leftarg = numeric,
rightarg = numeric
);
-- implementation of bitwise << operator for the numeric data type
create or replace function numeric_shift_left(leftarg numeric, rightarg numeric) returns numeric as
$$
begin
return leftarg * (2 ^ rightarg);
end;
$$ language plpgsql;
create operator << (
function = numeric_shift_left,
leftarg = numeric,
rightarg = numeric
);
do
$$
begin
assert 129401205912050919051920510251920501925::numeric &
12591205901209501209490409120949109249012040124::numeric = 375224963989548894071315746773172388;
assert 129401205912050919051920510251920501925::numeric #
12591205901209501209490409120949109249012040124::numeric = 12591206029860257193562230384726988007386197273;
assert 129401205912050919051920510251920501925::numeric |
12591205901209501209490409120949109249012040124::numeric = 12591206030235482157551779278798303754159369661;
assert 129401205912050919051920510251920501925::numeric >> 27 = 964114113986871533482674585669;
assert 129401205912050919051920510251920501925::numeric << 27 = 17367935857975642175460684922613477404993126400;
end;
$$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment