[fpc-devel] Extended($FFFFFFFFFFFFFFFF) = -1?

Hans-Peter Diettrich DrDiettrich1 at aol.com
Mon Mar 3 12:49:44 CET 2014

Ewald schrieb:
> On 03 Mar 2014, at 00:29, Hans-Peter Diettrich wrote:

>>> `-1` would then be $1 FFFF FFFF FFFF FFFF, whereas $FFFF FFFF
>>> FFFF FFFF would be $0 FFFF FFFF FFFF FFFF. It really is quite
>>> easy to store it like that and `fix` things [picking a fitting
>>> datatype] afterwards.
>> The datatype has to be constructed/determined first, and *if* there
>> exists a type with more than 64 bits, then it will be a signed
>> type, with a 65 bit (unsigned) subrange matching your needs. But if
>> no such type exists, you are lost.
> Yes, that is true, but there always is a 64 signed/unsigned type
> (perhaps not native). On machines where, for example, only 32 bit
> wide datatypes are allowed, the virtual subrange should be 33 instead
> of 65 bytes.

Subranges are expressed in low..hi notation, not in bits, meaning that 
the hi value must be expressable in a valid signed positive number.

> Anyway, that is the way how I parse constants. The important rule
> here is that you don't need the full 65 bit in the final
> representation. The signedness of the type can fix this loss of the
> one bit.

How (which data type) does *your* parser store untyped numerical constants?

IMO your problem arises from the fact that a bitpattern, with the 
highest of 64 bits set, cannot be stored in a larger (signed) type, as 
required. All such untyped constants will cause problems when assigned 
to typed variables. Test yourself what happens when you convert such an 
QWORD value into Extended.

>>> Anyway, then you have got backwards compatibility to take care
>>> of, since there will be someone out there who's code actually
>>> depends on this behaviour.
>> When we agree that a bitpattern of $FFFF FFFF FFFF FFFF can be
>> interperted differently on different 32 bit machines, as -1 or
>> -MaxInt,
> Why `on 32 bit machines`?

You're right, my guess of the number of bits was wrong.

> I'm fairly confident that this particular
> constant on this particular compiler version will generate the same
> outcome on every possible architecture out there (just change the
> `extended` to `single` in the original example, because extended
> tends to vary).

That's my expectation, too.

>> then it's obvious that such a textual representation should cause
>> an compilation error "not portable...". We know that such an error
>> message has not yet been implemented, but if you insist on writing
>> unportable code... :-]
> I insist on using a constant that is: - 64 bit wide - Only contains
> 1's - Is interpreted as an unsigned number wherever mathematical
> operations are performed.

Then you have to choose a different language. What will C++, C# or Java 
do in these cases?

> Those demands are quite portable, no?


> My original problem was easily solved with a typecast
> QWord(<gargantuan constant goes here>), so that was no longer an
> issue. What baffled me though was  the fact that this (mis-: in my
> opinion) mis-parsing of certain constants is by design.

What you observed was related to the argument passed to WriteLn. When 
WriteLn includes code to output a QWord, then the output should reflect 
the bitpattern (unsigned number). The output of an Extended value 
reflects the value converted from integral to floating point, and that 
conversion assumes signed values. IIRC the x87 FPU doesn't have an 
instruction to load unsigned integral values, so that no compiler has a 
chance to make it load an unsigned value.


More information about the fpc-devel mailing list