A quick note about this whole monkey business with type coercion in QBASIC

by rpgfan3233 (Login rpgfan3233)

QBASIC:
PRINT &H7FFF '32767
PRINT &H8000 '-32768
PRINT &HFFFF '-1
PRINT &H10000 '65536

PRINT &H7FFF& '32767
PRINT &H8000& '32768 (actually a LONG, not an unsigned value)
PRINT &HFFFF& '65535
PRINT &H10000& 'removes the trailing & symbol and outputs as above

I doubt people want to learn the new QB64 suffixes... Then again, I usually add a suffix for a quick fix when I can, so I'm not sure about things either way.

I think I can see your reasoning for switching the default treatment from signed to unsigned (optimized math routines often rely on bit manipulation, and non-decimal values complicate things because they can be signed or unsigned without you even seeing a sign).

In terms of C++, it is treated the same way, except in the case of bit shifts. There is no problem with left shifts (multiplication by 2), but right shifts (division) are of notable issue. If a value is unsigned, it uses the SHR instruction, which shifts in a 0 where the sign bit used to be. That isn't a problem. The problem is when signed values are used. Consider this FB code snippet:
DIM i AS INTEGER
i = -1

'inline ASM is /NOT/ something I want anytime soon
ASM
mov eax, [i]
shr eax, 1
mov [i], eax
END ASM
PRINT i
i = -1
PRINT i SHR 1

Output:
+2147483647 'the + isn't really there
-1

This is because i is signed. When you shift a signed integer, it uses the SAR instruction. This shifts in the sign bit. But you WANT to preserve the sign, right? Did you /see/ what happened? The right shift on the -1 at the bottom used SAR, and that resulted in -1 still. This is because -1 is 1111... (a theoretically infinite amount of 1s constrained by technical limitations) in binary. When you shift in the sign bit, you still get nothing but 1s. If you shift in a 0, you lose the sign, resulting in 2^(n - 1) bits being 1, where the n'th bit is the sign bit. I had an entire set of functions in C at one point, but I don't I have them anymore. Anyway, they wouldn't help much because there seems to be a special 64-bit type (non-native to the computer) that is used.

Basically what I did with multiplication and division is preserve the sign in a variable, remove the sign from the original value, do the proper operation and add the sign back. Also, it used a lot of bit manipulation (thanks to Chandler for getting me so worked up about binary and such), so it wasn't slow at all. Before I made multiplication and division algorithms that used binary, my best option was repeated addition/subtraction, which took forever to do 2147483647/2, as I found out.

I'm sure the signed/unsigned issue is just fine. Personally, I'd just as soon use DIM statements. There is also the option of the DEF* keywords, like DEFINT, DEFLNG, etc.

------------------
Waiting patiently for Windows 7, XHTML 2.0, CSS 3.0, PHP 6.0, the ratification of C++0x, and the day that I can code without logic troubles.

Posted on Apr 15, 2008, 10:20 PM
from IP address 12.208.126.190

Respond to this message   

Return to Index


Response TitleAuthor and Date
WOWZERS!!! on Apr 16
 * When you add this in, note that ! and # are not valid type suffixes.rpgfan3233 on Apr 16