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.c'. 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.c'. But in any case the minimal value of the macros will be 16. The interface contains the following external definitions:

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.

Variable `const unsigned char *zero_constant'

represents zero (unsigned) integer of any size.

Function `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'.

Function `set_integer_overflow_reaction'

        `void (*set_integer_overflow_reaction
                (void (*function) (void))) (void)'
        
changes reaction on integer overflow and returns previous overflow reaction function. There is analogous function
        `set_unsigned_integer_overflow_reaction'
        
for unsigned integer overflow.

Function `integer_maximum'

        `void integer_maximum   (int  size,  void  *result)'
        
creates given size (in bytes) maximal integer constant which is placed in memory whose address is given by the second parameter. There is analogous function
        `integer_minimum' and
        `unsigned_integer_maximum'.
        

Function `add_integer'

        `void add_integer (int size,
                           const void *op1, const void *op2,
                           void *result)'
        
makes integer addition of integers of given size. The function fixes overflow when result can not be represented by number of given size. There are analogous functions which implement other integer operations:
        `subtract_integer',
        `multiply_integer',
        `divide_integer',
        `integer_remainder'.
        
Also there are analogous functions
        `subtract_unsigned_integer',
        `multiply_unsigned_integer',
        `divide_unsigned_integer',
        `unsigned_integer_remainder'
        
for unsigned integers.

Function `integer_shift_left'

        `void  integer_shift_left (int size,  const void *operand,
                                   int bits, void *result)'
        
makes left shift of integer of given size on given number of bits. If number of bits is negative the function makes shift to right actually. The function fixes 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 integer operation
        `integer_shift_right'.  
Also there are analogous functions
        `unsigned_integer_shift_left' and
        `unsigned_integer_shift_right' for unsigned integers.
        

Function `integer_or'

        `void integer_or (int size, const void *op1, const void *op2,
                          void *result)'
        
makes bitwise `or' of integers of given size. There is analogous function which implement bitwise `and':
        `integer_and'.
        
Also there are equivalent functions
        `unsigned_integer_or',
        `unsigned_integer_and',
        
for unsigned integers.

Function

        `void integer_not (int size, const void *operand,
                           void *result)'
        
makes bitwise `not' of integer of given size. There is equivalent function for unsigned integer:
        `unsigned_integer_not'.
        

Function `eq_integer'

        `int eq_integer (int size, const void *op1, const void *op2)'
        
compares 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_integer',
        `gt_integer',
        `lt_integer',
        `ge_integer',
        and `le_integer'.
        
Also there are analogous functions
        `eq_unsigned_integer',
        `ne_unsigned_integer',
        `gt_unsigned_integer',                 
        `lt_unsigned_integer',
        `ge_unsigned_integer',
        and `le_unsigned_integer'
        
for unsigned integers.

Function `change_integer_size'

        `void  change_integer_size (int operand_size,
                                    const  void *operand,
                                    int result_size, void *result)'
        
changes size of integer. The function fixes overflow when result can not be represented by number of given size. There is analogous function
        `change_unsigned_integer_size'
        
for unsigned integers.

Function `integer_to_string'

        `char *integer_to_string (int  size, const void *operand,
                                  char *result)'
        
transforms integer of given size to decimal ascii representation. Sign is present in result string only for negative numbers. The function returns value `result'. There is analogous function
        `unsigned_integer_to_string'
        
for unsigned integers.

Function `integer_to_based_string'

        `char *integer_to_based_string (int  size, const void *operand,
                                        int base, char *result)'
        
transforms 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. The function returns value `result'. There is analogous function
        `unsigned_integer_to_based_string'
        
for unsigned integers.

Function `integer_from_string'

        `char *integer_from_string (int  size, const char *operand,
                                    void *result)'
        
skips all white spaces at the begin of source string and transforms the tail of the source string (decimal ascii representation with possible sign `+' or `-') to given size integer and returns pointer to first non digit in the source string. If the string started with invalid integer representation the result will be zero. The function fixes overflow when result can not be represented by number of given size. There is analogous function
        `unsigned_integer_from_string'
        
for unsigned integers. But sign `+' is believed to be not part of unsigned integer.

Function `integer_from_based_string'

        `char *integer_from_based_string (int  size, const char *operand,
                                          int base, void *result)'
        
skips 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 `-') to given size integer and returns 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 function fixes overflow when result can not be represented by number of given size. There is analogous function
        `unsigned_integer_from_based_string'
        
for unsigned integers. But sign `+' is believed to be not part of unsigned integer.


Next Previous Contents