Relearning MSX #27: Variables and arithmetic operations in MSX-C (part 2)Posted by Javi Lavandeira in How-to, MSX, Retro, Technology | September 30, 2015
In the previous post we saw a couple of variable types and the basic arithmetic operators. Today we’ll complete this part by taking a look at the bitwise operators and seeing a couple of characteristics of the char type.
Bitwise arithmetic operators
You may be aware already that computers store all data internally in binary. This is also the case with all the data types in MSX-C. As an example, the table below shows how some integer values are represented internally in the MSX computer memory:
The computer always works in binary, but in most cases we don’t care how MSX-C stores data internally because the compiler handles these details for us. However, there are situations when working with binary data makes sense, as in the case of working with graphics or programming hardware devices.
C provides several bitwise operators that we can use to operate with values bit by bit:
The first four operators in the list (&, |, ^ and ~) all have counterparts in BASIC: the AND, OR, XOR and NOT operators. We can summarize the way these work with these very simple tables:
Bitwise AND: &
In an AND operation, the result is 1 only if both operands are 1. It’s equivalent to multiplying both operands:
This can be used to turn off especific bits in a value. For example:
x: 0011001100110011 y: 0000000011111111 ---------------- x & y: 0000000000110011
In this case the 8 low bits of y were 1 and the 8 high bits were 0. As you can see in the example, the 8 low bits of the result are the same as the low bits of x, they are unchanged, while the high bits of the result are all 0.
Bitwise OR: |
In an OR operation, the result is 1 if either operand, or both, is 1:
We can use this property to turn on bits in a value:
x: 0011001100110011 y: 0000000011111111 ---------------- x | y: 0011001111111111
You can see in the result that all the bits that are on in either operand are also on in the result.
Bitwise XOR: ^
An XOR operation (eXclusive OR) is very similar to OR, but the result is 0 if both operands are 1:
XOR can be used to invert especific bits of a value: bits that are 1 in the second operand become switched in the result. It is also used extensively in cryptographic applications.
x: 0011001100110011 y: 0000000011111111 ---------------- x ^ y: 0011001111001100
Note that all bits of x that are 1 in y become inverted in the result.
Bitwise NOT: ~
This is the easiest of all. This operator inverts all the bits in the operand at the same time:
x: 0011001100110011 ---------------- ~x: 1100110011001100
The other two bitwise operators (<< and >>) are slightly different. Let’s take a look at them:
Arithmetic shift to the left: <<
This operator shifts the bits of the first operand to the left as many positions as indicated by the second operand. For example, the code:
x = x << 2;
would shift the bits of x two positions to the left:
Note that the two higher bits are discarded because they don’t fit in the result. The lower bits are filled with zeros.
This operator is very useful to perform fast multiplication: shifting the bits of x one position to the left is the same as multiplying by two, two positions is the same as multiplying by four, and so on.
Arithmetic shift to the right: >>
This works in exactly the same way as <<, but in this case the bits are shifted to the right:
Again, the bits that fall outside to the right are discarded, and zeroes are introduced to the left.
Shifting one bit to the right is the same as dividing by two; two bits to the right is the same as dividing by four, and so on.
Operations with the char type
So far we’ve seen all these operators that work with numeric values, but what are the operators to work with characters and text strings?
The answer is simple: C doesn’t have any operators to work with anything else than numeric values. The reason for this is that internally, everything in C is a number. char variables actually contain the ASCII code of the character assigned to them, which is just an 8-bit number. This means that, unlike in BASIC, we can use all these operators to perform operations with char values. Let’s see a very simple example:
This program declares a variable called c of type char and assigns the value ‘X’ to it. What actually happens at this point is that the MSX-C compiler replaces ‘X’ by the ASCII code of this character (the number 88). Then the program increments c so it is now 89, which happens to be the ASCII code of the character ‘Y’, and that’s exactly what putchar() prints on the screen. This wouldn’t work in BASIC:
In MSX-BASIC we would be getting an error if we tried to add a number to a string variable. Remember that C doesn’t care because internally every char is just a number.
Don’t worry, there are ways to handle text in MSX-C. This is done via library functions that we will see in another post.
We’ve seen the six bitwise arithmetic operations in C: AND (&), OR (|), XOR (^), NOT (~) and the two shift operators, << and >>. We’ve also learn that MSX-C handles everything internally as a number, and that we can use the arithmetic operators to work with char variables.
In the next post…
It seems that we’re going backwards: first we learnt how to print text and numbers on the screen, then we learn how to perform operations with numbers and characters. In the next post we will see how to actually read single characters and text strings from the keyboard.
This series of articles is supported by your donations. If you’re willing and able to donate, please visit the link below to register a small pledge. Every little amount helps.
Javi Lavandeira’s Patreon page