Next Previous Contents

10. Package for machine-independent arbitrary precision integer arithmetic

Abstract data `arithm' may be used for implementation of a cross-compiler. This abstract data implements arbitrary precision integer and unsigned integer number arithmetic by machine independent way. The implementation of the package functions are not sufficiently efficient in order to use for run-time. The package functions are oriented to implement constant-folding in compilers. This package is necessary because host machine may not support such arithmetic for target machine. For example, VAX does not support does not support more 32-bits integer numbers arithmetic.

The numbers in packages are represented by bytes in big endian mode, negative integer numbers are represented in complementary code. All sizes are given in bytes and must be positive. Results of executions of all functions can coincide with a operand(s). All functions of addition, subtraction, multiplication, division, evaluation of remainder, shift, changing size and transformation of string into number fix overflow. The overflow is fixed when result can not be represented by number of given size.

The interface part of the abstract data is file `arithm.h'. The implementation part is file `arithm.cpp'. The maximum length of integer number is suggested to be not greater then `MAX_INTEGER_OPERAND_SIZE'. The default value (128) of this macro can be redefined with corresponding C++ compiler option `-DMAX_INTEGER_OPERAND_SIZE=...' during compilation of file `arithm.cpp'. But in any case the minimal value of the macros will be 16. The interface contains the following external definitions:

Class `integer'

is auxialiary. It serves to describe common variables and functions for work with signed and unsigned integers (classes `signed_integer' and `unsigned_integer'). The class `integer' has the following members.

Public static variable `overflow_bit'

has only two values 0 or 1. The value `1' corresponds to overflow. The variable value are modified by all functions of addition, subtract, multiplication, division, evaluation of remainder, shift, changing size and transformation of string into number.

Public static variable `const unsigned char *zero_constant'

represents zero (unsigned) integer of any size.

Public static function `default_arithmetic_overflow_reaction'

           `void default_arithmetic_overflow_reaction (void)'
           
Originally reaction on all integer and unsigned integer overflow is equal to this function. The function does nothing. Reaction on overflow for integers or unsigned integers is called after setting up variable `overflow_bit'.

Classes `signed_integer' and `unsigned_integer'

are sub-classes of the class `integer'. The first class contains functions for implementation of signed integer arithmetic. The second one contains functions for implementation of unsigned integer arithmetic. The classes contains the following functions:

Static public function `set_overflow_reaction'

           `void (*set_overflow_reaction
                   (void (*function) (void))) (void)'
           
change reaction on integer overflow and returns previous overflow reaction function.

Static public functions `maximum'

           `void maximum   (int  size,  void  *result)'
           
create given size (in bytes) maximal integer constant which is placed in memory whose address is given by the second parameter.

Static public functions `add'

           `void add (int size, const void *op1,
                      const void *op2,
                      void *result)'
           
make integer addition of integers of given size. The functions fix overflow when result can not be represented by number of given size. There are analogous functions which implement other operations:
           `subtract',
           `multiply',
           `divide',
           `remainder'.
           

Static public functions `shift_left'

           `void  shift_left (int size,  const void *operand,
                              int bits, void *result)'
           
make left shift of integer of given size on given number of bits. If number of bits is negative the functions make shift to right actually. The functions fix overflow when result can not be represented by number of given size, i.e. in other words the opposite shift (to right) results in number not equal to source operand. There are analogous functions which implement another operation
           `shift_right'.
           

Static public function `_or_'

           `void _or_ (int size, const void *op1,
                       const void *op2,
                       void *result)'
           
make bitwise `or' of integers of given size. There are analogous functions which implement bitwise `and':
           `_and_'.
           

Static public functions

           `void _not_ (int size, const void *operand,
                        void *result)'
           
make bitwise `not' of integer of given size.

Static public functions `eq'

           `int eq (int size, const void *op1, const void *op2)'
           
compare two integers of given size on equality and returns 1 or 0 depending on result of the comparison. There are analogous functions which implement other integer operations:
           `ne',
           `gt',
           `lt',
           `ge',
           and `le'.
           

Static public functions `change_size'

           `void  change_size (int operand_size,
                               const  void *operand,
                               int result_size, void *result)'
           
change size of integer. The functions fix overflow when result can not be represented by number of given size.

Static public functions `to_string'

           `char *to_string (int  size, const void *operand,
                             char *result)'
           
transform integer of given size to decimal ascii representation. Sign is present in result string only for negative numbers (it is not possible for the function in class `unsigned_integer'). The functions return value `result'.

Static public functions `to_based_string'

           `char *to_based_string (int  size, const void *operand,
                                   int base, char *result)'
           
transform integer of given size to ascii representation with given base. The base should be between 2 and 36 including them. Digits more 9 are represented by 'a', 'b' etc. Sign is present in result string only for negative numbers (it is not possible for the function in class `unsigned_integer'). The functions return value `result'.

Static public functions `from_string'

           `char *from_string (int  size, const char *operand,
                               void *result)'
           
skip all white spaces at the begin of source string and transforms the tail of the source string (decimal ascii representation with possible sign `+' or `-' only for the function in class `signed_integer') to given size integer and return pointer to first non digit in the source string. If the string started with invalid integer representation the result will be zero. The functions fix overflow when result can not be represented by number of given size.

Static public functions `from_based_string'

           `char *from_based_string (int  size, const char *operand,
                                     int base, void *result)'
           
skip all white spaces at the begin of source string and transforms the tail of the source string (ascii representation with given base and with possible sign `+' or `-' only for the function in class `signed_integer') to given size integer and return pointer to first non digit in the source string. The base should be between 2 and 36 including them. Digits more 9 are represented by 'a' (or 'A'), 'b' (or 'B') etc. If the string started with invalid integer representation the result will be zero. The functions fix overflow when result can not be represented by number of given size.

Classes `sint' and `unsint'

Classes `signed_integer' and `unsigned_integer' containing only static function are simply written in C style. Object oriented implementation of integer arithmetic requires C++ template classes which is not supported all C++ compilers. Therefore if you define macro `NO_TEMPLATE' before inclusion of interface file, classes `sint' and `unsint' will be absent. The classes is parameterized by size of integers (in bytes). As the classes are subclasses of `signed_integer' and `unsigned_integer', you can members `overflow_bit', `set_overflow_reaction' to work with arithmetic overflow. The classes have the following memebers:

Public constructors `sint', `unsint'

           `sint (int value)', `sint (void)'
           `unsint (unsigned int value)', `unsint (void)'
           
can be used for creation integer with given value or zero integer.

Static public functions `max', `min'

           `class sint<size> max (void)'
           `class sint<size> min (void)'
           `class unsint<size> max (void)'
           `class unsint<size> min (void)'
           
create integers and unsigned integers of maximal and minimal value.

Public operators `+'

           `class sint<size> operator +
                               (const class sint<size> &op)'
           `class unsint<size> operator +
                               (const class unsint<size> &op)'
           
make integer addition of integers of given size. The operator fixes overflow when result can not be represented by number of given size. There are analogous operators which implement other operations:
           `-',
           `*',
           `/',
           `%'.
           

Public operators `<<'

           `class sint<size> operator << (int bits)'
           `class unsint<size> operator << (int bits)'
           
make left shift of integer on given number of bits. If number of bits is negative operator makes shift to right actually. The operators fix overflow when result can not be represented by number of given size, i.e. in other words the opposite shift (to right) results in number not equal to source operand. There are analogous operators which implement another operation (right shift)
           `>>'.
           

Public operators `|'

           `class sint<size> operator |
                             (const class sint<size> &op)'
           `class unsint<size> operator |
                               (const class unsint<size> &op)'
           
make bitwise `or' of integers. There are analogous operators which implement bitwise `and':
           `&'.
           

Public operators

           `class sint<size> operator ~ (void)'
           `class unsint<size> operator ~ (void)'
           
make bitwise `not' of integer of given size.

Public operators `=='

           `int operator == (const class sint<size> &op)'
           `int operator == (const class unsint<size> &op)'
           
compare two integers of given size on equality and returns 1 or 0 depending on result of the comparison. There are analogous operators which implement other integer operations:
           `!=',
           `>',
           `<',
           `>=',
           and `<='.
           

Public functions `to_str'

           `char *to_str (char *result)'
           
transform integer to decimal ascii representation. Sign is present in result string only for negative numbers (it is not possible for the function in class `unsint'). The functions return value `result'.

Public functions `to_based_str'

           `char *to_based_str (int base, char *result)'
           
transform integer to ascii representation with given base. The base should be between 2 and 36 including them. Digits more 9 are represented by 'a', 'b' etc. Sign is present in result string only for negative numbers (it is not possible for the function in class `unsint'). The functions return value `result'.

Public functions `from_str'

           `char *from_str (const char *operand)'
           
skip all white spaces at the begin of source string and transforms the tail of the source string (decimal ascii representation with possible sign `+' or `-' only for the function in class `signed_integer') to given integer and return pointer to first non digit in the source string. If the string started with invalid integer representation the result will be zero. The functions fixe overflow when result can not be represented by number of given size.

Public functions `from_based_str'

           `char *from_based_str (const char *operand, int base)'
           
skip all white spaces at the begin of source string and transforms the tail of the source string (ascii representation with given base and with possible sign `+' or `-' only for the function in class `signed_integer') to given integer and return pointer to first non digit in the source string. The base should be between 2 and 36 including them. Digits more 9 are represented by 'a' (or 'A'), 'b' (or 'B') etc. If the string started with invalid integer representation the result will be zero. The functions fixe overflow when result can not be represented by number of given size.

Template functions `new_size'

        `template <int result_size, int operand_size>
         inline void new_size (class sint<operand_size> &operand,
                               class sint<result_size> &result)'
        `template <int result_size, int operand_size>
         inline void new_size (class unsint<operand_size> &operand,
                               class unsint<result_size> &result)'
        
change size of integer. The functions fix overflow when result can not be represented by number of given size.


Next Previous Contents