20 July 2010

Unsigned to signed Byte data type

GFA-BASIC 32 provides two unsigned integer data types, the Card and Byte data type. The Card is a 16-bits integer and allows you to store positive integral values in the range from 0 to 65535. The Byte is 8-bits data type allowing you store a positive value from 0 to 255.

It is not important how many positive numbers the data type can hold. More importantly is the way how these values are handled in case of mathematic operations. The default operation GFA-BASIC 32 allows on integers is signed arithmetic, because all other integer data types are signed types. However, when you include a value stored in a Card or Byte GFA-BASIC expands the value to an unsigned 32-bits integer before using it in a calculation. So, when you store 255 in a Byte, the value 255 is used in calculations.

Now, suppose you need to use a Byte to store values like: –1, 0, 1. (The GFA-BASIC 32 editor uses these values to store line indenting information and I used it to implement block folding.) You can simply store these values into a Byte and in case of –1 all bits of the byte are set resulting in $FF (=255).

Dim b As Byte = -1  ' b = 255 ($FF)

When the Byte is used in a calculation, the value 255 is applied, which is not what we want. We need the Byte to behave as a signed value; $FF must be interpreted as –1. For this to happen we must GFA-BASIC 32 tell to interpret the Byte as a signed byte explicitly using the Sbyte() function. The Sbyte(b) function forces a conversion to a signed expansion to 32-bits.

Dim b As Byte = -1  ' b = 255 ($FF)
i% = b           ' i% = 255
i% = Sbyte(b)    ' i% = -1

In fact, the compiler uses a different assembler instruction to move the value from memory to the eax register (movzx eax, mem).

No comments:

Post a Comment