The arithmetic operations that can be performed on our drives are:
- addition;
- subtraction;
- multiplication;
- division.
These operations can be used (with some limitations) on any of the
available variables types from TML.
The variables available to the user in TML are integer, fixed and
long (all of them are signed variables, which means the Most
Significant Bit is the sign bit).
- the integer variable is 16 bit and can have any integer value in the
range -32768 ... +32767 (hex range is 0 ... 0xFFFF)
- the fixed variable is 32 bit and can have any fractional value in the
range -32768.0 ... +32767.99998 (hex range is 0 ... 0xFFFFFFFF)
- the long variable is 32 bit and can have any integer value in the
range -2147483648 ... +2147483647 (hex range is 0 ... 0xFFFFFFFF)
ADDITION and SUBTRACTION
The addition / subtraction can be done on any type of variables (as
long as they are the same type) and is pretty straight forward. The user just needs to take care not to exceed the maximum range of the signed
value as wraparound of the values will occur (example: 32767 + 1 will not
result in 32768 as this value is out of range for a signed 16 bit
variable, but will result in -32768).
Remark: The 32 bit variables can be further split into High part and Low
part (each of 16 bit) so adding/subtracting an integer to/from
long(H) or long(L), for example, is allowed as the instruction is actually
working with two 16 bit entities.
DIVISION
The division can only be done between a 32 bit variable and a 16 bit
variable and the result will always be stored in the 32 bit variable
(which means the initial value of the 32 bit variable will be lost
upon executing the division operation).
Since the 32bit variable can be either long or fixed, the result
will be set according to the type.
Attached can be found a demo project that includes the a control panel (6_Arithmetic Operations) for testing the division and multiplication.
In case of the division the control panel is used to do 2 division
operations: long / int and fixed / int
The used variables are: "fix_div" (fixed type) and "lg_div" (long type)
and, for example, they are initialized with the same value 100. The variable "int_div" is
the actual divider and is initialized with value 3.
After executing the TML commands "lg_div /= int_div;" and "fix_div /=
int_div;" (by pressing the button from the picture) the value 100 was discarded from both "fix_div'" and
"lg_div" variables and that they now hold the result according to
their type.
MULTIPLICATION
The multiplication can be done only between a 32 bit variable
and a 16 bit variable and the result is stored in special
variable called Product Register.
The Product Register is a 48 bit entity which can be accessed
in TML only as maximum 32 bit variable. To this end the MSB 32 bits of
the Product Register can be found under the variable named PRODH and the LSB
32 bis of the Product Register can be found under the variable named
PROD. It follows that a part of 16 bits from PRODH overlaps with a 16bit
part of PROD (more precisely PRODH(L) = PROD(H) all the time).
As in case of the addition, the user needs to take care to the wraparound situations.
Special multiplication situations
Let's multiply, for example, a fixed number, with no value wraparound, (fix_mlt = 1478.2345;) with an integer (int_mlt = 10;), .
The result, 14782.345, is within
the fixed variable limits. In this case (no wraparound)
the fractional result can be read from the PROD register (variable "fix_res_mlt = PROD").
The PRODH register will always have just the integer part of
the result (variable "lg_res_mlt").
If the multiplication result exceeds the range of the fixed
variable, then the result can not be read inside a fixed
variable. It can be read as a long type variable (basically,
ignoring the fractional part)
Multiplying a fixed number with value wraparound (fix_mlt = 1478.2345;) with and integer (int_mlt = 70;) will result a value (103476.38)
that exceeds the range of the fixed variables (the "fix_res_mlt" variable that returns a wrong value). Read in a long type variable the correct result will be obtained
(lg_res_mlt = PRODH;).
Remark: The fact that the fractional part ( ".38") is lost doesn't have such a big impact.
When a long is multiply with an integer, the things are simpler as long as the result
doesn't cause a value wraparound and can be rad from the PROD variable.
As example: 25000 * 25000 = 625,000,000 which is less than 2,147,483,647 (32 bit range).
If the result is outside the limits, not even reading the
PRODH register will not help as the number is simply bigger than
32bits.
As example:1547111875 * 10 = 15,471,118,750 which is outside range. In this case neither PROD nor PRODH have any usable value.