Trace:

modulo_20integer_20arithmetic

This shows you the differences between two versions of the page.

modulo_20integer_20arithmetic [2018/03/31 13:19] 127.0.0.1 external edit |
modulo_20integer_20arithmetic [2018/04/17 17:46] (current) tbest3112 Added syntax highlighting |
||
---|---|---|---|

Line 2: | Line 2: | ||

//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**:\\ \\ | //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 bb4w> | ||

B% = &40000001 | B% = &40000001 | ||

C% = &40000002 | C% = &40000002 | ||

A% = B% + C% | A% = B% + C% | ||

PRINT ~A% | 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:\\ \\ | 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 bb4w> | ||

B% = &40000001 | B% = &40000001 | ||

C% = &40000002 | C% = &40000002 | ||

A% = FN32(B% + C%) | A% = FN32(B% + C%) | ||

PRINT ~A% | PRINT ~A% | ||

+ | </code> | ||

where **FN32** is defined as follows:\\ \\ | where **FN32** is defined as follows:\\ \\ | ||

+ | <code bb4w> | ||

DEF FN32(V) | DEF FN32(V) | ||

WHILE V>&7FFFFFFF : V-=2^32 : ENDWHILE | WHILE V>&7FFFFFFF : V-=2^32 : ENDWHILE | ||

WHILE V<&80000000 : V+=2^32 : ENDWHILE | WHILE V<&80000000 : V+=2^32 : ENDWHILE | ||

= V | = 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:\\ \\ | 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 bb4w> | ||

A% = FN32(FN32(B% + C%) + FN32(D% + E%)) | A% = FN32(FN32(B% + C%) + FN32(D% + E%)) | ||

+ | </code> | ||

\\ | \\ | ||

==== How it works ==== | ==== 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. | 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. |

modulo_20integer_20arithmetic.1522502369.txt.gz ยท Last modified: 2018/03/31 13:19 by 127.0.0.1

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International