On 03 Mar 2014, at 12:49, Hans-Peter Diettrich wrote:

> 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.

That is why is use the word `virtual`. It is of course a more complex datatype 
than simply a subrange. See below.

> 
>> 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?

Roughly like this (syntax may be a bit awry, but you get the point):

TIntegerNumber = Record
Case SignedNess: TSignedNess of
        snPositive:     UValue: QWord;
        snNegative:  SValue: Int64;
End;

The parser detects wether there is a `-` in front of the constant and stores 
the right sign in the SignedNess field.

> 
> 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.

Yes, spot on :-)


> 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.
> 

That was the first example of this thread. The effect is the QWord becomes the 
mantissa of the extended, the exponent is set right and the sign bit is set to 
zero. But I believe the compiler must do this for me since (as you mention at 
the bottom of this quote) there is no instruction to load an unsigned integer 
into the 8087.


> 
> 
>>> 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?

Java I'll ignore, my C# is way too rusty and C/C++ won't parse the constant as 
is, because it overflows the normal 32 bit range. Here you have to type 
something like 0xffffffffffffffffLLU. I haven't tried casting the bugger into a 
float though.


> 
>> Those demands are quite portable, no?
> 
> No.

Alright, let me rephrase my demands:
        - I want to store the value 18446744073709551615 in any kind of 
variable without loss of precision.

Both set of demands are fine by me. Is that a more portable demand? ;-)


> 
>> 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.

Alright, that I did not know. Thanks for the info. I always assumed there was 
an instruction FULD, but it isn't there apparently.

--
Ewald

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to