Hi all,

Mark Rotteveel wrote:

>>> And I wondered if it isn't a bug that hex values with 1-4 digits are
>>> integer and not smallint. Or at least: shouldn't the engine have
enough
>>> context information to correctly convert 0x8000 to a smallint -32768
>>> instead of an integer 32768?
>>>
>>
>> It's documented, so it's not a bug.
>
> Ok, lets not call it a bug, but an area of potential improvement: based 
> on the context it should be possible to deduce that the literal should 
> be a smallint. Therefor it should be possible to handle 0x8000 as -32768

> when assigned to a smallint and as 32768 for an integer.

IMO, the real 'bug' is the notion that 0x8000 can be a negative number.

The fundamental issue here is that people have confused bit patterns with
binary numbers, and this confusion has since spread to hexadecimal
numbers.

E.g., in two's complement representation, the bit pattern for an 8-bit
integer with a value of -79 decimal is:

  10110001

But this doesn't mean that the *binary number* 10110001 corresponds to -79
decimal. 10110001 binary is 177 decimal, and -01001111 binary is -79
decimal.

Likewise, B1 hex = 177 decimal, and -4F hex = -79 decimal.

B1 hex is not, and should never be interpreted as, -79 decimal.

I've used an 8-bit example here for simplicity's sake, but the same
reasoning
holds for 16 bits, 32 bits, etcetera.

So, with hindsight (always easy), it would have been better never to
interpret
unsigned input as signed numbers. After all, if people want to enter a
negative
number in hex form, they can use a minus sign.

The way it is now, 0xFF507AB1 is parsed as -11502927 decimal, and
-0xFF507AB1
as 11502927 decimal (positive). That's pretty weird.

All that being said, this behaviour has been introduced and correctly
documented
(apart from the bit with the minus signs), so changing it now may break
existing
code. But let's not extend it to the smallint range and create one more
pitfall
for the users.

Meanwhile, the guy who wants to hex-feed -32768 into a smallint can simply
use
-0x8000, or more explicitly "cast(-0x8000 as smallint)".


Cheers,
Paul Vinkenoog


PS:

Border cases:

0x80000000 and -0x80000000 both translate to -2147483648.

0x8000000000000000 translates to -9223372036854775808,
but -0x8000000000000000 gives an integer overflow.

I think -0x80000000 should give and integer overflow too, since 0x80000000
is
interpreted as an INTEGER -2147483648, and there is no INTEGER
+2147483648.
(Using all-caps to distinguish the SQL type from the general term
'integer'.)


------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to