PostgreSQL:bit to smallint

时间:2013-04-19 05:18:00

标签: sql postgresql bit-manipulation 16-bit

据我所知,在PostgreSQL中你无法从十六进制或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        

因为这是&gt;比+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(考虑位)?

1 个答案:

答案 0 :(得分:5)

以下表达式适用于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