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:
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.
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.
represents zero (unsigned) integer of any size.
`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'.
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:
`void (*set_overflow_reaction
(void (*function) (void))) (void)'
change reaction on integer overflow and returns previous
overflow reaction function.
`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.
`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'.
`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'.
`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.
`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'.
`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.
`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'.
`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'.
`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.
`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 `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:
`sint (int value)', `sint (void)'
`unsint (unsigned int value)', `unsint (void)'
can be used for creation integer with given value or zero
integer.
`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.
`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:
`-',
`*',
`/',
`%'.
`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)
`>>'.
`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.
`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 `<='.
`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'.
`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'.
`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.
`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 <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.