所以我有两个整数 > 2 ^ 63 - 1 但是 < 2 ^ 64 -1. This is BIGINT UNSIGNED in most languages, but according to MySQL、PostgreSQL 和 SQLite 中数据库列类型的比较? (交叉映射),postogresql 中的数字(20)
问题是,当我尝试在两个无符号 bigint 之间进行 postgresql 异或运算时:
select 17418945696623429624::numeric(20) # 17418945696623429624::numeric(20);
=>
ERROR: operator does not exist: numeric # numeric
对于任何小于 2 ^ 63 -1 的非“数字”整数,它都可以正常工作。
改写:如何在大于 2 ^ 63 - 1 但小于 2 ^ 64 - 1 的两个数字之间执行异或运算?前任。我如何在 PostgreSQL 中将 17418945696623429624 与其自身进行异或?
看起来 PostgreSQL 有一个 bigint 类型——你为什么不使用它?
我使用 pgplsql 创建了一系列按位运算符函数来满足这一确切要求。这是异或的示例:
create or replace function numeric_xor(leftarg numeric(1000), rightarg numeric(1000)) returns numeric as
$$
declare width int = 32;
declare modulo bigint := 2 ^ width;
declare b1 bigint := 0;
declare b2 bigint := 0;
declare r numeric(1000) := 0;
declare 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
);
do
$$
begin
assert 129401205912050919051920510251920501925::numeric # 12591205901209501209490409120949109249012040124::numeric = 12591206029860257193562230384726988007386197273;
end;
$$;
其他运算符可以在这里找到:https://gist.github.com/allfro/d93cbc6980f38cf309555eff77381ced