Question

As far as I was able to understand in PostgreSQL you are not able to convert from hex or bit to smallint or the other way around.

To convert from int2 to bit16 one can do something like this:

select ((((-32768)::int2)::int4)::bit(32)<<16)::bit(16)
    Result: 1000000000000000

But how can we do it the other way around?

I have a int2 flag where I want to set the highest bit. But since I can't use my bit operations with int2 I have to convert it to int4 before, so I can do this. Something like this:

SELECT flags, 
       (flags | x'8000'::integer) myInt2Result 
  FROM MyTable;

Then I would use myInt2Result to call other processes. To make it more easy to try, lets imagine flags was a smallint with value 2560:

SELECT 2560::int2, (2560::int2 | x'8000'::integer)
    RESULT: 35328        

Since this is > than +32767 and I don't have an unsigned smallint in PostgreSQL I cannot cast it directly to int2 (smallint out of range).

Also: in PostgreSQL we cannot do

x'8000'::int2 (it would be really handy) 
OR
x'8000'::integer::int2 (smallint out of range) 

Is there a way to do this in PostgreSQL or will I have to convert my int4 into a int2 myself (considering the bits)?

Était-ce utile?

La solution

The following expressions work for me in PostgreSQL 9.1:

select ((-32768)::int2)::int4::bit(16);
==>  X'8000'

select ((('X8000'::bit(16))::bit(32)::int4) >> 16)::int2;
==> -32768

EDIT: a bit of evidence that this works:

-- 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top