Skip to main content
added 106 characters in body
Source Link
Jim D
  • 560
  • 2
  • 8

Using the expression

result = -(x & mask) + (x & !mask)

where mask=2^(n-1) yields the result you want. The (x & mask) isolates the sign bit and (x & !mask) is the offset. When the sign bit is not set, (x & mask) == 0 and (x & !mask) is the result. When the sign bit is set, -(x & mask) == -2^(n-1) and (x & !mask) is the offset from the most negative number.

Next we convert the hexadecimal string to a raw representation by using HEXTORAW(). The raw representation is cast to an integer with UTL_RAW.CAST_TO_BINARY_INTEGER().

Assuming 16 bit:

select 
  x,
  -BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32768) 
    +BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32767)  
  from (select '8508' x from dual);

DB Fiddle example

Note: You probably want to do the utl_raw.cast_to_binary_integer(hextoraw(...)) once instead of twice.

Using the expression

result = -(x & mask) + (x & !mask)

where mask=2^(n-1) yields the result you want. The (x & mask) isolates the sign bit and (x & !mask) is the offset. When the sign bit is not set, (x & mask) == 0 and (x & !mask) is the result. When the sign bit is set, -(x & mask) == -2^(n-1) and (x & !mask) is the offset from the most negative number.

Next we convert the hexadecimal string to a raw representation by using HEXTORAW(). The raw representation is cast to an integer with UTL_RAW.CAST_TO_BINARY_INTEGER().

Assuming 16 bit:

select 
  x,
  -BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32768) 
    +BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32767)  
  from (select '8508' x from dual);

DB Fiddle example

Using the expression

result = -(x & mask) + (x & !mask)

where mask=2^(n-1) yields the result you want. The (x & mask) isolates the sign bit and (x & !mask) is the offset. When the sign bit is not set, (x & mask) == 0 and (x & !mask) is the result. When the sign bit is set, -(x & mask) == -2^(n-1) and (x & !mask) is the offset from the most negative number.

Next we convert the hexadecimal string to a raw representation by using HEXTORAW(). The raw representation is cast to an integer with UTL_RAW.CAST_TO_BINARY_INTEGER().

Assuming 16 bit:

select 
  x,
  -BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32768) 
    +BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32767)  
  from (select '8508' x from dual);

DB Fiddle example

Note: You probably want to do the utl_raw.cast_to_binary_integer(hextoraw(...)) once instead of twice.

Source Link
Jim D
  • 560
  • 2
  • 8

Using the expression

result = -(x & mask) + (x & !mask)

where mask=2^(n-1) yields the result you want. The (x & mask) isolates the sign bit and (x & !mask) is the offset. When the sign bit is not set, (x & mask) == 0 and (x & !mask) is the result. When the sign bit is set, -(x & mask) == -2^(n-1) and (x & !mask) is the offset from the most negative number.

Next we convert the hexadecimal string to a raw representation by using HEXTORAW(). The raw representation is cast to an integer with UTL_RAW.CAST_TO_BINARY_INTEGER().

Assuming 16 bit:

select 
  x,
  -BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32768) 
    +BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32767)  
  from (select '8508' x from dual);

DB Fiddle example