Hello,
I just stubled over a bug in the conversion of hex values to Ulongint or Longint Data Types in the 32-bit version of the compiler. If the 32. bit is set and the upper 32 bits are empty, the upper 32 bits are replaced with &FFFFFFFF:
dim as ulongint a
a = &h0000000000000001
print hex(a,16),a
a = &h0000000070000001
print hex(a,16),a
a = &h0000000080000001
print hex(a,16),a
a = &h80000001
print hex(a,16),a
a = &h8000000080000001
print hex(a,16),a
a = &h0000000180000001
print hex(a,16),a
The default data type for integer number literals is
Integer, that's signed 32bit on 32bit. Then if the sign bit is set, it will be sign-extended when converted to 64bit, this is normal.It can be avoided by adding a number literal suffix like
uor[u]ll, saying that the number is aUInteger(then it will do zero-extension instead of sign-extension) or a[U]LongInt(then there's no extension done at all):Last edit: dkl 2015-07-05
But that works when using a decimal literal without suffix:
When using an hexadecimal literal without suffix, is the implicit conversion for assignment is distorted by that first conversion to 32bit?
Why that first conversion?
Integer number literals can be implicitly converted to UInteger if the value is large enough to not fit into Integer. But it doesn't work for &b/&o/&h literals. I don't know what the reason for that was.
Logically, if there's a prefix of zeroes, then the lower Integer should be in any case converted to unsigned by the constructor of the ULngInt/Longint. If you compare:
Then, the Longint to negative is an (unexpected) exception. And these are quite difficult to find.
Yea, that's something we've talked about before... in FB it works much like C at the moment, i.e. leading zeroes are ignored, but that is not always intuitive.
Made an entry for that here: [feature-requests:#295]
Personally I'm not 100% sold on changing the behaviour yet, but who knows.
Related
Feature Requests: #295