Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
QB664PE v3.10.0 is now live for X-Mas!!
#41
It's actually a case where doing a fix allowed it to break.

In the past, &H would error out, skip out of the manual evaluation process, and go into the automatic catch-all evaluation routines (which is where we do things such as various string manipulation like "a" + "b" which would, of course, be "ab".)  By fixing it so that it no longer glitches and errors out like it used to, we're now properly returning the value that we tell it to give us -- which is, the improper value!

Let me showcase part of the issue for you guys:

Code: (Select All)
Print &HFFFF, Hex$(&HFFFF)

Dim l As Long, i As _Integer64
l = &HFFFF
i = &HFFFF
Print l, Hex$(l)
Print i, Hex$(i)

Now the results here are a print out of:

Quote:-1        FFFF
-1        FFFFFFFF
-1        FFFFFFFFFFFFFFFF

The problem here?

This goes back to the QBASIC roots of the language, and which we have to follow to maintain backwards compatibility.  QBASIC didn't have any _UNSIGNED numbers, so all values had to be represented as signed numbers.

FFFF was considered to be a 2-byte integer, and as a signed integer, the value is indeed -1.

The problem comes from the fact that -1 as an integer is represented as FFFF, and as an long it's represented as FFFFFFFF...  And if we turn that hex representation into an unsigned value, it becomes much different!    65535 vs 4billion-something!!

So our internal math eval is now properly reading the values for us, but it's improperly returning everything as an unsigned integer64 back to us.

&HFFFF would return 65535, when -- by default in QBASIC and QB64 -- it should return -1.
&HFFFFFFFF would return the 4billion-something value, when it too should actually return -1.  

(One is just -1 as an integer, while the other is -1 as an long.)

So that's one glitch here.  I take full responsibility for this one.  I've just always *assumed* when working with hex, one was using *unsigned* values.  QBASIC didn't have unsigned values, so the result has to return as signed values to be backwards compatible.   This part of the glitch is 100% on me, and should be rather simple to fix.



Now, unrelated to this signed/unsigned glitch, our fix is also pointing out that there are now instances where a negative sign is getting appended to the values before we evaluate them.  Matt has hunted this glitch down for us, and should be able to sort it out soon(tm).

(Note:  SOON in this case is SOON(TM!!), as this is the heart of the holiday season and everyone is busy as heck!  We'll get to it, as soon as we can get to it.  Big Grin )

If you want a good demo of both glitches in action, just run this little code:

Code: (Select All)
Const blue = &HFF0000FF
Print Hex$(blue), Hex$(-blue)

The result you get is:
Quote:FFFFFFFF0FF000F1          FF0000FF

That first value (which I may have copied wrong --/shrug -- ) is basically the unsigned integer64 value of NEGATIVE blue.  The negative glitch is hitting the value we specify, as well as the fact that it's being returned as an integer64 value to us, by default.

That second value goes to show that if we negate that number, once it becomes positive, it is -- indeed -- the value we assigned to blue.  (It's just an unsigned integer64 value, but hex$ strips off those leading 8 zeros, so you'd never actually know it was an unsigned int64 unless you did a LEN on it, or some nice Steve told you...)



So multiple fixes are required for this:

1) To fix the return type so that it's a signed value, to match QB45 behavior.
2) To remove that improper negation which is happening to certain values with &H.  (&B and probably &O as well.)
Reply
#42
Quote:@RhoSigma - Wish people would just once look there befor complaining, its rather sucking to maintain the wiki and knowing nobody use it when needed.
This is a fundamental problem! I first became aware of this in Linux forums. Questions were asked again and again, 99% of which were covered in the first 50 to 100 pages of The Kofler. - To explain: The Kofler was once the standard work for Linux; It probably still is today.

Der Kofler

I still have version 2. This was the first time that I could installed and ever managed Linux on the command line.

Ok, it cost money, and hardly any of the Hurray Linux fans wanted to pay a cent for the "Fuck the Windows" system, but it's characteristic.
I learned about this in all forums, whether Linux, BSD or Windows. I don't think this will ever change, not fundamentally.

Yes, that is frustrating!
Reply
#43
(12-27-2023, 11:02 PM)SMcNeill Wrote: It's actually a case where doing a fix allowed it to break.

In the past, &H would error out, skip out of the manual evaluation process, and go into the automatic catch-all evaluation routines (which is where we do things such as various string manipulation like "a" + "b" which would, of course, be "ab".)  By fixing it so that it no longer glitches and errors out like it used to, we're now properly returning the value that we tell it to give us -- which is, the improper value!

Let me showcase part of the issue for you guys:

Code: (Select All)
Print &HFFFF, Hex$(&HFFFF)

Dim l As Long, i As _Integer64
l = &HFFFF
i = &HFFFF
Print l, Hex$(l)
Print i, Hex$(i)

Now the results here are a print out of:

Quote:-1        FFFF
-1        FFFFFFFF
-1        FFFFFFFFFFFFFFFF

The problem here?

This goes back to the QBASIC roots of the language, and which we have to follow to maintain backwards compatibility.  QBASIC didn't have any _UNSIGNED numbers, so all values had to be represented as signed numbers.

FFFF was considered to be a 2-byte integer, and as a signed integer, the value is indeed -1.

The problem comes from the fact that -1 as an integer is represented as FFFF, and as an long it's represented as FFFFFFFF...  And if we turn that hex representation into an unsigned value, it becomes much different!    65535 vs 4billion-something!!

So our internal math eval is now properly reading the values for us, but it's improperly returning everything as an unsigned integer64 back to us.

&HFFFF would return 65535, when -- by default in QBASIC and QB64 -- it should return -1.
&HFFFFFFFF would return the 4billion-something value, when it too should actually return -1.  

(One is just -1 as an integer, while the other is -1 as an long.)

So that's one glitch here.  I take full responsibility for this one.  I've just always *assumed* when working with hex, one was using *unsigned* values.  QBASIC didn't have unsigned values, so the result has to return as signed values to be backwards compatible.   This part of the glitch is 100% on me, and should be rather simple to fix.



Now, unrelated to this signed/unsigned glitch, our fix is also pointing out that there are now instances where a negative sign is getting appended to the values before we evaluate them.  Matt has hunted this glitch down for us, and should be able to sort it out soon(tm).

(Note:  SOON in this case is SOON(TM!!), as this is the heart of the holiday season and everyone is busy as heck!  We'll get to it, as soon as we can get to it.  Big Grin )

If you want a good demo of both glitches in action, just run this little code:

Code: (Select All)
Const blue = &HFF0000FF
Print Hex$(blue), Hex$(-blue)

The result you get is:
Quote:FFFFFFFF0FF000F1          FF0000FF

That first value (which I may have copied wrong --/shrug -- ) is basically the unsigned integer64 value of NEGATIVE blue.  The negative glitch is hitting the value we specify, as well as the fact that it's being returned as an integer64 value to us, by default.

That second value goes to show that if we negate that number, once it becomes positive, it is -- indeed -- the value we assigned to blue.  (It's just an unsigned integer64 value, but hex$ strips off those leading 8 zeros, so you'd never actually know it was an unsigned int64 unless you did a LEN on it, or some nice Steve told you...)



So multiple fixes are required for this:

1) To fix the return type so that it's a signed value, to match QB45 behavior.
2) To remove that improper negation which is happening to certain values with &H.  (&B and probably &O as well.)

Fixes for this here has been pushed into the repo for testing and approval of the other devs.  If all goes good and the fix for this doesn't break something somewhere else (which is entirely possible with CONST, as complicated as it's became), it should get merged into the repo in the next few days and then be availble in the next release we offer.  Wink
Reply
#44
I am a bit surprised by the rant on not reading the documentation in this case...
This is not about knowing/understanding that 32bit color-values are unsigned long and should be assigned to variables declared _Unsigned Long or with ~& type-specifier. I think this is common practice in most code.

This has to do with a (undocumented) change in behavior of Const. Also the wiki shows examples where Const is used without type-specifier behind the value like on the Const wiki page itself Const PI = 3.14159 instead of  Const PI = 3.14159# which shows that for Const declarations it is less common to do that and also the wiki does not give clear directions that you should.
Most examples in the wiki that contain Const do not show type-modifiers behind the value.

But apart from that, Const is now acting different from what it has done for years.
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#45
I am a bit surprised by the rant on not reading...
Reply
#46
The QuickBasic 4.5 manual says the following about constants:

The type constant is either explicit through the type identifier, or determined by the type of expression. Without a type identifier, the simplest type in which the constant can be represented is always assigned.

Strings are always define as string constants.

Code: (Select All)

Const Wert1 = 344 '-> Integer
Const Wert2 = 3.44 '-> Single, simplest type

'Error
'Const Stadt = Berlin

'Correct
Const Stadt = "Berlin"

Print Wert1
Print Wert2
Print Stadt
Reply
#47
(12-29-2023, 02:09 PM)Kernelpanic Wrote: The QuickBasic 4.5 manual says the following about constants:

The type constant is either explicit through the type identifier, or determined by the type of expression. Without a type identifier, the simplest type in which the constant can be represented is always assigned.

Strings are always define as string constants.

Code: (Select All)

Const Wert1 = 344 '-> Integer
Const Wert2 = 3.44 '-> Single, simplest type

'Error
'Const Stadt = Berlin

'Correct
Const Stadt = "Berlin"

Print Wert1
Print Wert2
Print Stadt

Aye, and the current issue comes from here: 

Quote:The type constant is either explicit through the type identifier, or determined by the type of expression. Without a type identifier, the simplest type in which the constant can be represented is always assigned.

In QB45, there were no unsigned variable types.
By the ruleset above, &HFFFF has no explicit type identifier. The simplest type that it can be represented in, is a SIGNED INTEGER. That's -1.
By the same ruleset, &HFFFFFFFF has no explicit type identifier. The simplest type that it can be represented in, is a SIGNED LONG. That's also a value of -1.

&HFFFF + &HFFFFFFFF = -2

Seems odd as heck to me, but that's what it is, when neither value has an explicit type identifier.

QB64 hasn't been doing this properly, and that's being fixed -- and that fix may change folks code which relied upon the improper handing of these values. You can read about (and respond to) those changes in the topic here: https://qb64phoenix.com/forum/showthread...0#pid22330

No need to keep a discussion this important on the back page, hidden dozens of replies deep, in a topic simply announcing that a new version has been released. Wink
Reply
#48
(12-29-2023, 09:16 AM)SMcNeill Wrote: [quote="So that's one glitch here.  I take full responsibility for this one.  I've just always *assumed* when working with hex, one was using *unsigned* values.  QBASIC didn't have unsigned values, so the result has to return as signed values to be backwards compatible.   This part of the glitch is 100% on me, and should be rather simple to fix." pid="22297" dateline="1703718120"]
Damn! Thing is, I always use hex the way you had "always assumed." Always hex number unsigned. I guess, no huge big deal, it's going to take some trial and error to see what old programs of mine will break. I guess I never ran into the problem in my Qbasic days.

Wait. If I do x = Val("&h" + "ffff")

Will I still get x = 65535
Reply
#49
(12-29-2023, 08:53 PM)bert22306 Wrote:
(12-29-2023, 09:16 AM)SMcNeill Wrote: Damn! Thing is, I always use hex the way you had "always assumed." Always hex number unsigned. I guess, no huge big deal, it's going to take some trial and error to see what old programs of mine will break. I guess I never ran into the problem in my Qbasic days.

Wait. If I do x = Val("&h" + "ffff")

Will I still get x = 65535
yes.
Reply
#50
Hi @bert22306,

This is just about setting a Const and using other than decimal number bases.
b = b + ...
Reply




Users browsing this thread: 2 Guest(s)