Modulo+integer+arithmetic

//by Richard Russell, July 2007//

Some implementations of BBC BASIC (for example Acorn versions) allow you to add (or subtract) two 32-bit integers in such a way that the result 'wraps around', i.e. is evaluated **modulo 2^32**. For example in such versions the following code prints the hexadecimal value **80000003**:

code format="bb4w" B% = &40000001 C% = &40000002 A% = B% + C%     PRINT ~A% code However in //BBC BASIC for Windows// this code results in the **Number too big** error because it attempts to load **A%** with a value outside the valid range of an integer variable (-2147483648 to +2147483647).

Generally the BBC BASIC for Windows behaviour is more consistent, and is less likely to give rise to unexpected results and potential program bugs. However on rare occasions the 'modulo' behaviour can actually be useful.

If you want to reproduce the modulo arithmetic behaviour with BBC BASIC for Windows you can use code similar to the following:

code format="bb4w" B% = &40000001 C% = &40000002 A% = FN32(B% + C%) PRINT ~A% code where **FN32** is defined as follows:

code format="bb4w" DEF FN32(V) WHILE V>&7FFFFFFF : V-=2^32 : ENDWHILE WHILE V<&80000000 : V+=2^32 : ENDWHILE = V code This will work correctly so long as you are adding or subtracting only two values. If you need to add three or more values you can either run the program in ***FLOAT 64** mode or split the expression up into operations on no more than two values, for example:

code format="bb4w" A% = FN32(FN32(B% + C%) + FN32(D% + E%)) code

How it works
The floating-point variable **V** consists of a 32-bit mantissa and an 8-bit exponent. Superficially one might imagine that, when containing an integer value, it can represent only the same numeric range as a 32-bit integer variable; if that were the case the code in **FN32** would not work, since the numeric overflow would result in a loss of accuracy.

However because of the way (40-bit) floating-point numbers are represented they can in fact contain, without any loss of precision, the equivalent of a **33-bit** integer, that is any integer value from -4294967296 TO +4294967295. Thus they can contain, without overflow or truncation, the sum or difference of any two 32-bit integers; therefore the reduction to a valid 32-bit range using the code in FN32 can take place accurately.