Mixing Signed and Unsigned variables in expressions

Started by trastikata, Jul 17, 2023, 07:27 PM

Previous topic - Next topic

trastikata

With regards to my math cod optimization from the other topic, I just found out that we have to be very careful mixing signed and unsigned variables in longer expressions. Strange to realize it after so much time :)

- Finding number one - a longer expression will be handled as unsigned until it "hits" a signed variable, this will produce the wrong result if f>e because the first part (e - f) * a will be evaluated as unsigned multiplication even though g and d are signed variables.

Dim a As Word
Dim b As Word
Dim c As Word
Dim d As SWord
Dim e As Word
Dim f As Word
Dim g As SWord

g = (e - f) * a + (b - c) / (c - d)


- Finding number two - placing the result into a Signed variable will not call signed division and multiplication in an expression, this will produce the wrong result if f>e or/and c>b or/and d>c

Dim a As Word
Dim b As Word
Dim c As Word
Dim d As Word
Dim e As Word
Dim f As Word
Dim g As SWord

g = (e - f) * a + (b - c) / (c - d)

TimB


When I code I always think the compiler is going to have problems with long maths statements. So I always break it down into smaller segments and think about what it has to do with regards to var types.
Then I step it through in a VSM to see if I'm getting the results I expect.

I have been stung in the past where I did not know how the var would be treated giving odd results that I wasted hours running down rabbit holes trying to solve.

top204

Mixing signed and unsigned integer variables within an expression will always cause problesm, no matter what language it is. In C and C++, some compilers produce a warning that "significant bits will be lost". Because signed integer variables are a different format to unsigned types (2's complement) and the upper bit signifies positive or negative values and a complement value is used if the bit is set. So the value 65535 is very different to a signed 16-bit variable, because the last bit (bit-15) is set, so the value is now negative, etc... So mixing them will cause problems because the compiler cannot swap and change the signs inside an expression, otherwise, there would need to be a huge library for every variable type and every variable sign type for all the different operators, and then some more.

You can temporarily cast the integer variables as signed within an expression or comparison using something like: "MyWord1.SWord + MyWord2.SWord" or "If MyWord1.Sword = -200 Then". But it is always better not to mix signed and unsigned integer variables unless cast. The same can be done with signed integer variables, and temporarily cast them as unsigned.

trastikata

Quote from: top204 on Jul 18, 2023, 12:11 PMYou can temporarily cast the integer variables as signed within an expression or comparison using something like: "MyWord1.SWord + MyWord2.SWord" or "If MyWord1.Sword = -200 Then".

Great, thanks Les.

I generally break long expressions as TimB said, but that's not always feasible, so being able to "forcefully" call signed math is real help.