First | Next | Previous | Last | Glossary | About

# Data types, modifiers and more arithmetic operators

- Integer modifiers
- Float and double
- Pre and post increment/decrement and Unary minus
- Arithmetic assignment operators
- Tutorial

## Integer modifiers

C++ allows the integer data type to be qualified or modified:

Modifier | Example | Explanation
    short
    short int v1,v2;
    short x;
| A short integer usually occupies half the space of a normal integer and the normal integer depends on the machine word size.
    long
    long int v1,v2;
    long x;
| A four byte long integer will allow values from 2,147,483,647 to 2,147,483,648 (231 - 1 to -231)
    unsigned
    unsigned int v1,v2;
    unsigned x;
| An unsigned integer occupies the same space as an integer but has no negative values, for example for a two-byte integer the range of values would be 0 to 216 - 1 i.e. 65535. A four byte integer would range from 0 to 232 - 1 i.e. 4294967295
    ushort
    ulong
    ushort int v1,v2;
    ulong x;
| The unsigned short and long modifiers can be abbreviated.

Here is an example program:

    //ex8.cc - Integers
    #include <iostream>
    #define LARGE 0x7fff

    int main()
    {
     long int val1 = 131071L;

     long int bigval = 2147483647;
     unsigned short byteval = 254;
     short twos = 0x80, moretwos;

     cout << LARGE << endl;
     cout << (LARGE - 01777) << endl;
     cout << (LARGE - 0X7000) << endl;
     cout << val1 << endl;
     cout << bigval << endl;
     cout << val1 << " "
          << bigval << " "
          << (val1 + bigval) << endl;
     cout << byteval << endl;
     cout << twos << endl;
     moretwos = byteval + twos;
     cout << moretwos << endl;

     return 0;
    }

Here is the output:

     32767
     31744
     4095
     131071
     2147483647
     131071 2147483647 -2147352578
     254
     128
     382

LARGE is a symbolic constant and is given a hexadecimal value. The variable val1 is initialised to 131071. The L is optional and means treat the literal constant as a long integer. This will ensure that the sign is extended correctly.

The first cout statement displays LARGE. Even though LARGE is initialised with a hexadecimal value, it is displayed in decimal.

The second cout statement displays the result of (LARGE - 01777). Since 01777 is prefixed with zero it is treated as an octal value.

The third cout statement displays the result of (LARGE - 0X7000). Since 0X7000 is prefixed with 0X it is treated as a hexadecimal value.

The fourth and fifth cout statements simply display val1 and bigval as decimals.

The sixth cout statement displays val1 and bigval again and then displays the result of the expression (val1 + bigval). Although both variables are positive and the operation is addition, the result is a negative number. This is because the result has overflowed.

cout statements 7 and 8 display the variables byteval and twos as decimals.

The expression moretwos = byteval + twos; is interesting because it shows that for this compiler (egcs) a short integer is bigger than 8 bits.

In summary:

- Integer size varies with machines.
- Integer size can be modified by the use of long, short, unsigned qualifiers.

Return to top of page

## Float and double

float and its partner double are used to declare floating point variables, i.e. variables that will hold real numbers.

float f1,f2;

  In theory a double variable declaration means that the precision of the floating point variable is doubled. If float can contain 8 digits then double can contain 16 digits.

double f3,f4;

> float.

here is an example:

    //ex9.cc - float and formatting
    #include <iostream>

    int main()
    { float v1,
            v2 = 98.967; //initialise v2
      double dv1;        //twice the precision
                         //of v1 and v2

      cout << v1
           << endl;  //NaN : v1 not initialised
      cout << v2
           << endl;
      v1 = 100.0 * v2;
      cout << v1 &
           << " "
           << v1
           << endl;
      dv1 = 1000.0 * v1;
      cout << dv1
           <<  " "
           << dv1
           << endl;

      return 0;
    }

the program is quite simple but I have put a comment //NaN : v1 not initialised. All this means is that you may get some odd results if you try to use an uninitialised variable. NaN means Not a Number.

You may or may not know that floating point values have quite a complex internal representation which stores numbers in Exponent + Fraction form rather like scientific notation.

For example a floating point number might be stored as:

    0 0111111 11111111111111111

now the example is an oversimplification but its shows a float as having three parts. From the left:

- 0 - a sign bit for the fraction,
- 0111111 - a seven bit exponent in what is called excess 64 form
- and a 16 bit fraction which:
  1. is normalised - this means the most significant bit is non-zero,
  2. has an implied binary point to the left of the MSB of the fraction.

a valid float must fit the form shown above and if it breaks that form, as an uninitialised variable might, then it is not a number. For instance an uninitialised variable might have fraction that is not normalised - hence NaN.

Return to top of page

## Pre and Post increment/decrement operators and Unary minus

Apart from the arithmetic operators you have used so far the languages C and C++ provide some operators that are quite distinctive:

- the increment and decrement operators
- assign and arithmetic modifiers

The increment and decrement operators are unary operators which means they operate with a single operand:

    ++x,   --x are prefix addition and subtraction

and are equivalent to x = x + 1 and x = x - 1 respectively.

    x++,   x-- are postfix addition and subtraction

and are also equivalent to x = x + 1 and x = x - 1 respectively.

So what is the difference? It depends on how the operators are used, k = ++x gives a different result from k = x++. Try it yourself! You will find that in both cases x in incremented but k has two different values. If x = 4 then in the case of k = ++x k becomes 5 but in the case of k = x++ k becomes 4. The operators are named prefix and postfix appropriately. The prefix operator increments first and then uses the value of the incremented operand, the postfix operator uses the value of the operand and then increments it.

What values do k and x have after the following code has executed?

    a) x = 5; k = x-;
    b) x = 5; k = --x;

There is one operator I have failed to mention - the unary minus - it tends to be overlooked, poor thing!

Unary minus is quite simple: k = -k, it has the effect of multiplying the operand by -1.

Return to top of page

## arithmetic assignment operators

    +=,	-=,	*=,	/=,	%=

Thelast bunch of arithmetic operators is the group (shown here) known as the arithmetic assignment operators. I think of them as arithmetic modifiers for the assignment operator.

They are used like this:

    k += 4; which means k = k + 4	k -= 4; which means k = k - 4
    k *= 4; which means k = k * 4	k /= 4; which means k = k / 4
    k %= 4; which means k = k % 4

    int main()
    {
     int x = 0,y = 2,z = 1025;
     float a = 0.0,b = 3.14159,c = -37.234;

                   /* incrementing */
       x++;        /* This increments x */
       ++x;        /* This increments x */
       z = y++;    /* z = 2, y = 3 */
       z = ++y;    /* z = 4, y = 4 */

                   /* decrementing */
       y--;        /* This decrements y */
       --y;        /* This decrements y */
       y = 3;
       z = y--;    /* z = 3, y = 2 */
       z = --y;    /* z = 1, y = 1 */

                   /* arithmetic assignment */
       a += 12;    /* This adds 12 more to a */
       a *= 3.2;   /* This multiplies a by 3.2 */
       a -= b;     /* This subtracts b from a */
       a /= 10.0;  /* This divides a by 10.0 */

      return 0;
    }

The pre/post variations of the increment and decrement operators tend to puzzle people at first. Why have two variations on the same operator?

How does z = y++ differ from z = ++y?

In the first case then value of y is assigned to x then y is incremented. In the second case y is incremented then its new value is assigned to z. Each statement results in a different value of z.

Return to top of page

## Tutorial

Return to top of page

First | Next | Previous | Last | Glossary | About

Copyright © 1999 - 2001 David Beech