Numbers

The data types for numbers are integer and float. In contrast to integer, the type float can also store numbers with decimal places. It is therefore a decimal number type.

When decimal numbers are mentioned in the field of Computing, this normally refers to a specific kind of decimal numbers, namely floating comma numbers. We shall briefly explain what this means.

When you multiply the numbers 1.5 and 2.5, the result is 3.75. If you work with fixed commas and you assume that only one decimal place is used, then 3,75 has to be rounded to a single decimal place. This means that in a fixed comma format, the result will be 3.8.

In contrast, floating comma numbers are not rounded, and all the necessary decimal places are kept. This means that the number of decimal places is variable (it "floats"), hence the name.

The types integer and float are the only ones that can be mixed in an operation:

12 + 44.09 // <-- allowed

"abcd" + 5 // <-- not allowed

Arithmetic operations

Generally speaking, arithmetic operations can be applied to all numbers. For this, mathematical order applies. If several operations of the same level are applied in sequence, they are processed from left to right:

2 + 4 * 3 / 2 - 1

4 * 3 is calculated first (12), because multiplication has a higher priority than addition. Division (12 / 2) follows next. The result (6) is added to 2 (8) and finally, the subtraction is processed (8 – 1). The result of the calculation above is therefore 7.

However, you can use brackets to change the sequence in which the operations are processed:

(2 + 4) * 3 / (2 – 1)

In this case, the addition is carried out first, before multiplying the result of the addition (6 * 3). The subtraction (2 - 1) is carried out before the division, because it appears in brackets. Finally, the result of the addition is divided by the result of the subtraction (18 / 1). This time, the result is:

The result of every operation has a particular data type. This depends on the operators used. If all the operators have the type integer (as in the two examples above), then the result also has the type integer. If at least one operand has the type float, then the result will also have the type float, as in the following example, where the last operand is a decimal number:

2 + 4 * 3 / 2 – 1.0

Please also note the following special case in this context: A calculation only uses the type float when it appears for the first time. This means that the calculation

3 / 2 – 1.0

will somewhat unexpectedly have the result 0.0, because the division (i.e. the first calculation) is carried out between two integers (3 / 2). Since integers do not have decimal places, they are ignored (1.5 becomes 1). Next, the value 1,0 is subtracted from this result and it is only in this calculation that the type float is used.

The following example presents a different case, because the division (the first operation) already uses float:

3 / 2.0 – 1

The result of this calculation is therefore 0.5.

In addition to arithmetic operations, a number of other operations can be applied to integers. One of these operations is the calculation of a remainder value (see chapter "Operators"). The operator for this is %. This follows the convention in languages such as C, C++, C#, and others:

5 % 2

The result of this operation is 1, because 2 fits twice into 5 (2 * 2 = 4). The remainder value for 5 is therefore 1.

The % operator can also be applied on decimal numbers. However, since decimal places can not form a remainder value, they are ignored in this operation. In this case, TDM Studio issues a warning since it is possible that the operation wasn't intended to work in this way.

Bit manipulation

Operations that can be applied to the type integer, but not to float are called bit manipulations. This includes operations which can move the set and not set bits within a byte. The characters used for this are << (twice smaller than) for movement to the left and >> (twice greater than) for movement to the right.

Let us take the number 15 as an example. In binary display, this appears as:

0000000000001111

If we now move to the left (say by 4 bits), the statement would look like this:

integer number = 15 << 4;

After the assignment, number will contain the value 240, because all bits were moved by four places to the left and freed bits to the left are not used again (they are padded with zeros):

0000000011110000

If we move the bits back by four places, we arrive back at the value 15:

number = number >> 4;

You should exercise caution when using this, because it is a so-called arithmetic shift.

For a shift to the right, the sign bit (the one furthest to the left) is copied instead of padding the freed place with a zero. This means that a negative value remains negative, even after the shift.

Let us consider the following bit sequence as an example:

1111000000000000

The leftmost bit is the sign bit. This means that the number is negative. if these bits are shifted to the right, the freed places are not padded with zeros but with ones. For a shift by four places, this results in:

1111111100000000

You must keep this in mind when using the shift operators.

Bitwise conjunctions are less problematic. They are either bitwise AND (represented by &), bitwise OR (represented by |) or bitwise exclusive OR (represented by ^).

Let us consider the numbers 10 and 7 to see the effect that these conjunctions have:

00001010

00000111

If these two bit sequences are joined with AND, the following rules are relevant:

1 & 1 = 1

1 & 0 = 0

0 & 1 = 0

0 & 0 = 0

This means that a bitwise conjunction of the above sequences with AND would have the following result:

00000010

because (processed from right to left):

0 & 1 = 0

1 & 1 = 1

0 & 1 = 0

1 & 0 = 0

0 & 0 = 0

0 & 0 = 0

0 & 0 = 0

0 & 0 = 0

If the two bit sequences are joined with OR, the result is a set bit wherever at least one of the places is a set bit. The following rules apply:

1 | 1 = 1

1 | 0 = 1

0 | 1 = 1

0 | 0 = 0

if we look at this again for our two bytes, we notice it in the result:

00001010

OR

00000111

=

00001111

In a conjunction with exclusive OR, only one or the other bit may be set, hence the name exclusive OR. If both bits are set, the result is zero:

1 ^ 1 = 0

1 ^ 0 = 1

0 ^ 1 = 1

0 ^ 0 = 0

This means:

00001010

XOR

00000111

=

00001101

The last bitwise operator available in TDM Studio is the bitwise negation. This reverses all bits to their opposite. A set bit becomes not set and vice versa. The character for this operation is the tilde (~). It is places before the value to be negated:

integer x = ~7;

integer y = ~x;

The effect can be seen in the following byte:

~00000111

=

11111000

You can re-create all these examples by for example writing the following into the variables of a task:

Trace(TRACELEVEL_INFO, Format("~7 = {0}", ~7));

Trace(TRACELEVEL_INFO, Format("7 ^ 10 = {0}", 7 ^ 10));

Trace(TRACELEVEL_INFO, Format("7 | 10 = {0}", 7 | 10));

Trace(TRACELEVEL_INFO, Format("7 &amp; 10 = {0}", 7 &amp; 10));