To begin with, let’s get some bits of terminology out of the way. An operation (such as a mathematical calculation) is defined by an operator— + for addition, for example, or*for multiplication. The values that an operator acts upon are called operands, so in an expression such as2*3, the operands are2and3.+ for addition, for example, or * for multiplication. The values that an operator acts upon are called , so in an expression such as 2*3 , the operands are 2 and 3 .To begin with, let’s get some bits of terminology out of the way. An operation (such as a mathematical calculation) is defined by an — + for addition, for example, or * for multiplication. The values that an operator acts upon are called , so in an expression such as 2*3, the operands are 2 and 3.
Because the multiplication operator requires two operands, it is called a binary operator. Some other operators only require one operand, and these are called unary operators. An example of a unary operator is the minus sign in–2. The minus sign acts on one operand—the value 2—and changes its sign. This contrasts with the binary subtraction operator in expressions such as4 - 2, which acts on two operands, the4and the2.Introducing Literals
In C++, fixed values of any kind, such as42, or2.71828, or"Mark Twain", are referred to as literals.In Chapter 1, when you were outputting text strings to the screen, you used a string literal—a constant defined by a series of characters between a pair of double quotes, of which"Mark Twain"is an example. Now you’ll investigate the types of literals that are numeric constants. These are the ordinary numbers you meet every day: your shoe size, the boiling point of lead, the number of angels that can sit on a pin—in fact, any defined number.
There are two broad classifications of numeric constants that you can use in C++:
You use an integer when you’re dealing with what is evidently a whole number: the number of players on a team, for example, or the number of pages in a book. You use a floating-point value when the values aren’t integral: the circumference of a circle divided by its diameter, for example, or the exchange rate of the UK£ against the US$.
Floating-point numbers are particularly helpful when you’re dealing with very small or very large quantities: the weight of an electron, the diameter of the galaxy, or the velocity of a bat out of hell, perhaps. The term “floating-point number” is used because while these values are represented by a fixed number of digits, called the precision, the decimal point “floats” and can be moved in either direction in relation to the fixed set of digits.
Letting the Point Float
Look at these two numbers:
Both numbers have seven digits of precision, but they’re very different numbers, the first being an extremely small number and the second being very large. A floating-point representation of each number on the left is shown to its right. Multiplying the number by a power of 10 shifts the decimal point in the base number, 1.234567. This flexibility in positioning the decimal point allows a huge range of numbers to be represented and stored, from the very small to the very large, in a modest amount of memory.
You’ll look at how to use integers first, as they’re the simpler of the two. You’ll come back to working with floating-point values as soon as you’re done with integers.Integer Literals
You can write integer literals in a very straightforward way. Here are some examples:
-123 +123 123 22333
Here, the+and-signs in the first two examples are examples of the unary operators I mentioned earlier. You could omit the+in the second example, as it’s implied by default, but if you think putting it in makes things clearer, that’s not a problem. The literal+123is the same as123. The fourth example is the number that you would normally write as 22,333, but you must not use commas within an integer literal. If you include a comma, the compiler is likely to treat your number as two numbers separated by the comma.
You can’t write just any old integer value that you want, either. To take an extreme example, an integer with 100 digits won’t be accepted. There are upper and lower limits on integer literals, and these are determined by the amount of memory that’s devoted to storing each type of integer value on the computer that you’re using. I come back to this point a little later in the chapter when I discuss integer variables, and I also cover some further options for specifying integer literals.
Of course, although I’ve written the examples of integer literals as decimal values, inside your computer they’re stored as binary numbers. Understanding binary arithmetic is quite important in programming, so in case you’re a little rusty on how binary numbers work, I’ve included a brief overview in Appendix E. If you don’t feel comfortable with binary and hexadecimal numbers, I suggest you take a look at the overview in Appendix E before continuing with the next section.
Hexadecimal Integer Literals
The previous examples of integer literals were decimal integers, but you can also write integers as hexadecimal values. To indicate that you’re writing a hexadecimal value, you prefix the number with0xor0X, so if you write0x999, you’re writing a hexadecimal number with three hexadecimal digits. Plain old999, on the other hand, is a decimal value with decimal digits, so the value will be completely different. Here are some more examples of integer literals written as hexadecimal values:
You’ll remember that in Chapter 1 you saw hexadecimal notation being used in escape sequences that defined characters. What you’re looking at here is different— you’re defining integers. You’ll come back to defining character literals later in this chapter.
The major use for hexadecimal literals is when you want to define a particular pattern of bits. Because each hexadecimal digit corresponds to 4 bits in the binary value, it’s easy to express a particular pattern of bits as a hexadecimal literal. You’ll explore this further in the next chapter.
Octal Integer Literals
You can also write integers as octal values—that is, using base 8. You identify a number as octal by writing it with a leading zero. Here are some examples of octal values:
Octal values 0123 077 010101
Corresponding decimal integers 83 63 4161
Of course, octal numbers can only have digit values from 0 to 7. Octal is used very infrequently these days, and it survives in C++ largely for historical reasons from the time when there were computers around with a word length that was a multiple of 3 bits. However, it’s important to be aware of the existence of octal numbers, because if you accidentally write a decimal number with a leading zero, the compiler will try to interpret it as octal.
CAUTION Don’t write decimal integer values with a leading zero. The compiler will interpret such values as octal (base 8), so a value written as 065 will be equivalent to 53 in decimal notation.
As far as your compiler is concerned, it doesn’t matter which number base you choose when you write an integer value—ultimately, it will be stored in your computer as a binary number. The different ways available to you for writing an integer are there just for your convenience. You could write the integer value fifteen as15, as0xF, or as017. These will all result in the same internal binary representation of the value, so you will choose one or other of the possible representations to suit the context in which you are using it.Integer Arithmetic
The basic arithmetic operations that you can carry out on integers are shown in Table 2-1.
Table 2-1. Basic Arithmetic Operations
% Modulus (the remainder after division)
The operators in Table 2-1 work largely in the way you would expect, and notice that they are all binary operators. However, the division operation is slightly idiosyncratic, so let’s examine that in a little more detail. Because integer operations always produce an integer result, an expression such as11/4doesn’t result in a value of2.75. Instead, it produces2. Integer division returns the number of times that the denominator divides into the numerator. Any remainder is simply discarded. So far as the C++ standard is concerned, the result of division by zero is undefined, but specific implementations will usually have the behavior defined and, in some cases, will provide a programmatic means of responding to the situation, so check your product documentation.
Figure 2-1 illustrates the different effects of the division and modulus operators.
The modulus operator,%, which is sometimes referred to as the remainder operator, complements the division operator in that it provides a means for you to obtain the remainder after integer division if you need it. The expression11%4results in the value3, which is the remainder after dividing 11 by 4. When either or both operands of the modulus operator are negative, the sign of the remainder is up to the particular C++ implementation you’re using, so beware of variations between different systems. Because applying the modulus operator inevitably involves a division, the result is undefined when the right operand is zero.
Let’s see the arithmetic operators in action in an example.
blog comments powered by Disqus