据我在PostgreSQL中所能理解的,您无法从hex或bit转换为smallint或以其他方式转换。
要将int2转换为bit16,可以执行以下操作:
select ((((-32768)::int2)::int4)::bit(32)<<16)::bit(16)
Result: 1000000000000000
但是我们如何才能做到这一点呢?
我有一个int2标志,我想在其中设置最高位。但是由于我无法在int2中使用我的位操作,因此我必须先将其转换为int4,所以我可以这样做。像这样:
SELECT flags,
(flags | x'8000'::integer) myInt2Result
FROM MyTable;
然后,我将使用myInt2Result调用其他进程。
为了更容易尝试,让我们想象一下标志是一个值为2560的smallint:
SELECT 2560::int2, (2560::int2 | x'8000'::integer)
RESULT: 35328
由于此值大于+32767,并且在PostgreSQL中没有unsigned smallint,因此无法将其直接转换为int2(smallint超出范围)。
另外:在PostgreSQL中,我们不能做
x'8000'::int2 (it would be really handy)
OR
x'8000'::integer::int2 (smallint out of range)
有没有一种方法可以在PostgreSQL中做到这一点,或者我必须自己将int4转换为int2(考虑位)?
最佳答案
以下表达式在PostgreSQL 9.1中对我有用:
select ((-32768)::int2)::int4::bit(16);
==> X'8000'
select ((('X8000'::bit(16))::bit(32)::int4) >> 16)::int2;
==> -32768
编辑:这工作的一点证据:
-- int2 to bit16 and back
create temp table test1 (x int2);
insert into test1 select generate_series(-32768,32767)::int2;
select x from test1 where x != ((x::int4::bit(16) ::bit(32)::int4) >> 16)::int2;
==> no rows selected
-- bit16 to int2 and back
create temp table test2 (x bit(16));
insert into test2 select generate_series(0,65536)::bit(16);
select x from test2 where x != (((x::bit(32)::int4)>>16)::int2) ::int4::bit(16);
==> no rows selected