[fpc-devel] Do bitwise operation (1 or 2) acre about the sign ? (Giving sign related hints on compilation)

Martin lazarus at mfriebe.de
Mon Jan 14 16:44:31 CET 2013


On 14/01/2013 15:27, Hans-Peter Diettrich wrote:
> Martin schrieb:
>> On 14/01/2013 13:54, ik wrote:
>>> On Mon, Jan 14, 2013 at 3:11 PM, Martin <lazarus at mfriebe.de> wrote:
>>>> Actually not so much about the hint, as about the fact that in the 
>>>> below
>>>> example fpc extends the operands to 64 bits.
>>>>
>>>> program Project1;
>>>> var
>>>>    x: cardinal;
>>>>    i, j: integer;
>>>> begin
>>>>    i:= x or j
>>>> end.
>>> i is an "integer" type, and you try to assign it a number that might
>>> have 64 bit value.
>>> It might overflow the memory itself.
>>>
>>
>> That is not it.
>>
>> program Project1;
>> var
>>   x: cardinal;
>>   j: integer;
>>   i: qword; // int64;
>> begin
>>   i:= x or j
>> end.
>>
>> Happens too, if the left site is int64 or qword.
>>
>> I understand, the hint is about the fact that doing 64 bit 
>> calculations on 32 bit are more expensive. But that was not my question.
>>
>> Why does " signed_32bit or unsigned_32bit " need to be extended and 
>> calculated in 64 bit? "or" operates on a set of bits. Afaik for the 
>> "or" statement, there is no diff in signed/unsigned?
>
> During above calculation ("or") a sign extension is required because 
> the result *must* have a definite sign. Else a following comparison of 
> e.g. (x or j)>0 could not determine a result.

This is casting a "set of bits" (neither signed, nor unsigned - a set is 
not a number at all) into a number. This only needs to have a 
definition, if it should cast to signed or unsigned type.

Extending it, and then using the 64 bit result will mean that, the sign 
will be excluded from the "or" operation. This is not expected at all. 
The sign is stored in one of the bits (and part of the set of bits), in 
should be affected.
Here in an example
    signed($80000001)  OR unsigned($80000002)
will be extended to
    signed($ffffffff80000001)  OR signed($0000000080000002)
the sign is now present in the to pupper dword / for the unsigned value 
this is empty. Therefore the sign is simply copied from the signed 
value, without being ever affected by the "or" itself.

The operation could be done with 32 bit
set_of_bits := s32 or u32;

and if you do
    set_of_bits > int
    set_of_bits + int
or anything then set_of_bits must be cast to an int type. It needs to be 
defined if that should cast in to signed or unsigned.








More information about the fpc-devel mailing list