Tải bản đầy đủ (.pdf) (10 trang)

A Complete Guide to Programming in C++ part 17 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (248.4 KB, 10 trang )

139
Converting Arithmetic
Types
This chapter introduces implicit type conversions, which are performed in
C++ whenever different arithmetic types occur in expressions.
Additionally, an operator for explicit type conversion is introduced.
chapter
8
140

CHAPTER 8 CONVERTING ARITHMETIC TYPES

IMPLICIT TYPE CONVERSIONS
Integer promotions
bool
short
char, signed char, unsigned char
int
int
unsigned int
unsigned short
if int equals long
if int equals short
Type hierarchy
Example
short size(512); double res, x = 1.5;
res = size / 10 * x; // short -> int -> double
int
long double
double
float


unsigned long
long
unsigned int
int
not-existent, if int
equals long
IMPLICIT TYPE CONVERSIONS

141
C++ allows you to mix arithmetic types in a single expression — in other words, the
operands of an operator can belong to different types. The compiler automatically per-
forms implicit type conversion, where a common type, which allows the operation in ques-
tion to be performed, is assigned for the values of both operands. You can generally
assume that the “smaller” type will be converted to the “larger” type. The assignment
operator is an exception to this rule and will be discussed separately.
The result of an arithmetic operation belongs to the common type used to perform
the calculation. However, comparison expressions will be bool types no matter what
type of operands are involved.
ᮀ Integer Promotion
Integer promotion is first performed for any expression:
■ bool, char, signed char, unsigned char, and short are converted to
int
■ unsigned short is also converted to int if the int type is greater than
short, and to unsigned int in all other cases.
This type conversion is performed so as to preserve the original values. The boolean
value false is converted to 0 and true is converted to 1.
Thus, C++ will always use int type values or greater when performing calculations.
Given a char variable c, the values of c and 'a' in the expression
Example: c < 'a'
will be converted to int before being compared.

ᮀ Usual Arithmetic Type Conversions
If operands of different arithmetic types still occur after integer promotion, further
implicit type conversions along the lines of the hierarchy on the opposite page will be
necessary. In this case, the type of the operand with the highest rank in the hierarchy is
applied. These type conversions and integer promotions are collectively known as usual
arithmetic type conversions.
In our example, size/10 * x, the value of size is first promoted to int before an
integer division size/10 is performed. The interim result 50 is then converted to dou-
ble
and multiplied by x.
Usual arithmetic type conversions are performed for all binary operators and the con-
ditional operator ?: provided the operands belong to an arithmetic type, the only excep-
tions being the assignment operator and the logical operators && and ||.
142

CHAPTER 8 CONVERTING ARITHMETIC TYPES
Sign bit(= 0 ↔ not negative)
Sign bit(= 0 ↔ not negative)
00001010
Extension to int (here 16 bit)
The value 10 is preserved.
000000000000 1010
2
6
2
14
2
13
2
8

2
7
2
1
2
0
2
5
2
4
2
3
2
2
2
1
2
0
• • • • • • • •
Binary representaion of the integer 10
as value of type signed char (8 bits):


Sign bit(= 1 ↔ negative)
Sign bit(= 1 ↔ negative)
11110110
Extension to int (here 16 bit)
The value –10 is preserved.
111111111111 0110
2

6
2
14
2
13
2
8
2
7
2
1
2
0
2
5
2
4
2
3
2
2
2
1
2
0
••• •••••
Binary representaion of the integer –10
as value of type signed char (8 bits):



The value of a negative number changes if the bit pattern is interpreted as unsigned. The bit pattern
1111 0110 of –10, for example, corresponds to the unsigned char value
246 == 0*2
0
+ 1*2
1
+ 1*2
2
+ 0*2
3
+ 1*2
4
+ 1*2
5
+ 1*2
6
+ 1*2
7

NOTE

PERFORMING USUAL ARITHMETIC TYPE CONVERSIONS
Converting signed integers
a) Converting a positive number
b) Converting a negative number
The bit pattern of –10 is computed by starting with the bit pattern of 10 and generat-
ing the binary complement (see Binary Representation of Numbers in the appendix).
PERFORMING USUAL ARITHMETIC TYPE CONVERSIONS

143

Usual arithmetic type conversions retain the value of a number provided it can be repre-
sented by the new type. The procedure for type conversion depends on the types
involved:
1. Conversion of an unsigned type to a larger integral type
Examples: unsigned char to int or unsigned int
Zero extension is performed first. During this process, the bit pattern of the num-
ber to be converted is expanded to match the length of the new type by adding
zeros from the left.
2. Conversion of a signed type to a larger integral type
■ The new type is also signed
Examples: char to int, short to long
Signed integers are represented by generating the binary complement. The
value is retained by performing sign extension. As shown in the example on the
opposite page, the original bit pattern is expanded to match the length of the
new type by padding the sign bit from the left.
■ The new type is unsigned
Examples: char to unsigned int, long to unsigned long
In this case the value of negative numbers is not retained. If the new type is of
the same length, the bit pattern is retained. However, the bit pattern will be
interpreted differently. The sign bit loses its significance (see the note oppo-
site).
If the new type is longer, sign extension is performed first and the new bit
pattern is then interpreted as unsigned.
3. Conversion of an integral type to a floating-point type
Examples: int to double, unsigned long to float
The number is converted to an exponential floating-point type and the value
retained. When converting from long or unsigned long to float, some
rounding may occur.
4. Conversion of a floating-point type to a larger floating-point type
Examples: float to double, double to long double

The value is retained during this type conversion.
144

CHAPTER 8 CONVERTING ARITHMETIC TYPES

IMPLICIT TYPE CONVERSIONS IN ASSIGNMENTS
Example 1:
int i = 100;
long lg = i + 50; // Result of type int is
// converted to long.
Example 2:
long lg = 0x654321; short st;
st = lg; //0x4321 is assigned to st.
Example 3:
int i = –2; unsigned int ui = 2;
i = i * ui;
// First the value contained in i is converted to
// unsigned int (preserving the bit pattern) and
// multiplied by 2 (overflow!).
// While assigning the bit pattern the result
// is interpreted as an int value again,
// i.e. –4 is stored in i.
Example 4:
double db = –4.567;
int i; unsigned int ui;
i = db; // Assigning –4.
i = db – 0.5; // Assigning –5.
ui = db; // –4 is incompatible with ui.
Example 5:
double d = 1.23456789012345;

float f;
f = d; // 1.234568 is assigned to f.
IMPLICIT TYPE CONVERSIONS IN ASSIGNMENTS

145
Arithmetic types can also be mixed in assignments. The compiler adjusts the type of the
value on the right of the assignment operator to match the type of the variable on the
left.
In the case of compound assignments, calculations using normal arithmetic type con-
versions are performed first before type conversion is performed following the rule for
simple assignments.
Two different cases can occur during type conversion in assignments:
1. If the type of the variable is larger than the type of the value to be assigned, the
type of the value must be promoted. The rules for usual arithmetic type conver-
sions are applied in this case (see Example 1).
2. If the type of the value to be assigned is larger, this type must be “demoted.” The
following procedures are followed depending on individual circumstances:
a. Conversion of an integral type to a smaller type:
■ the type is converted to a smaller type by removing the most significant
byte(s). The bit pattern that remains will be interpreted as unsigned, if the
new type is also unsigned, and as signed in all other cases. The value can
only be retained if it can be represented by the new type (see Example 2).
■ when converting an unsigned type to a signed type of the same scale,
the bit pattern is retained and will be interpreted as signed (see Example
3).
b. Conversion of a floating-point type to an integral type
The decimal part of the floating-point number is removed. For example, 1.9
converts to the integer 1. Rounding can be achieved by adding 0.5 to a posi-
tive floating-point number or subtracting 0.5 from a negative floating-point
number. This would allow for converting (1.9 + 0.5) to 2.

If the resulting integer is too large or too small for the new type, the result
is unpredictable. This particularly applies to converting negative floating-
point numbers to unsigned integers (see Example 4).
c. Conversion of a floating-point type to a smaller type
If the floating-point number falls within the range of the new type, the value
will be retained, although the accuracy may be compromised. If the value is
too large to be represented by the new type, the result is unpredictable (see
Example 5).
146

CHAPTER 8 CONVERTING ARITHMETIC TYPES
// Ellipse.cpp
// The program draws an ellipse.
// The points (x,y) on an ellipse with center (0,0)
// and axes A and B satisfy:
// x = A*cos(t), y = B*sint(t) for 0 <= t <= 2*PI .
//
#include <iostream>
#include <cmath> // Prototypes of sin() and cos()
using namespace std;
#define CLS (cout << "\033[2J")
#define LOCATE(z,s) (cout <<"\033["<<(z)<<';'<<(s)<<'H')
#define DOT(x,y) (LOCATE(y,x) << '*')
#define PI 3.1416
#define Mx 40 // The point (Mx, My) is the
#define My 12 // center of the ellipse.
#define A 25 // Length of main axis
#define B 10 // Length of subsidiary axis
int main()
{

int x, y; // Screen coordinates.
CLS;
// 0 <= t <= PI/2 is a 1/4-circle:
for( double t = 0.0 ; t <= PI/2 ; t += 0.03)
{
x = (int) (A * cos(t) + 0.5);
y = (int) (B * sin(t) + 0.5);
DOT( x+Mx, y+My);
DOT( x+Mx,-y+My);
DOT(-x+Mx, y+My);
DOT(-x+Mx,-y+My);
}
LOCATE(24,0);
return 0;
}

MORE TYPE CONVERSIONS
Sample program
MORE TYPE CONVERSIONS

147
ᮀ Implicit Type Conversions in Function Calls
In the case of function calls, arguments with arithmetic types are converted to the types of
the corresponding parameters, similarly to conversions in assignments.
Example: void func( short, double); // Prototype
int size = 1000;
// . . .
func( size, 77); // Call
The function func() has two parameters belonging to the short and double types.
However, the function is called using two int arguments. This leads to implicit conver-

sion of the value of size to short and the integer 77 to double.
When an int is converted to short the compiler issues a warning, since some data
loss may occur. You can use explicit type conversion to avoid warnings during type con-
version.
ᮀ Explicit Type Conversion
It is possible to convert the type of an expression explicitly using the cast operator
(type).
Syntax: (type) expression
This converts the value of an expression to the given type. Explicit type conversion is
also known as casting.
The cast operator (type) is a unary operator and thus has a higher precedence than
the arithmetic operators.
Example: int a = 1, b = 4;
double x;
x = (double)a/b;
In this example the value of a is explicitly converted to a double. Following the con-
ventions of usual implicit type conversion, b is also converted to double and a floating-
point division is performed. The exact result, 0.25, is assigned to the variable x.
Without casting, an integer division with a result of 0 would have occurred.
C++ has additional operators for explicit type conversion—the cast operator
dynamic_cast<>, for example. These operators, which are described in later chapters,
are required for special circumstances, for example, to perform type checking at runtime
when converting classes.
exercises
148

CHAPTER 8 CONVERTING ARITHMETIC TYPES
// Convert.cpp —> Demonstrates type conversions.
#include <iostream>
#include <iomanip>

using namespace std;
int main()
{
char v_char = 'A';
cout << "v_char: " << setw(10) << v_char
<< setw(10) << (int)v_char
<< endl;
short v_short = –2;
cout << "v_short: " << dec << setw(10) << v_short
<< hex << setw(10) << v_short
<< endl;
unsigned short v_ushort = v_short;
cout << "v_ushort: " << dec << setw(10) << v_ushort
<< hex << setw(10) << v_ushort
<< endl;
unsigned long v_ulong = v_short;
cout << "v_ulong: " << hex << setw(20) << v_ulong
<< endl;
float v_float = –1.99F;
cout << "v_float: " << setw(10) << v_float << endl;
cout << "(int)v_float: " << setw(10)
<< dec << (int)v_float << endl;
return 0;
}

EXERCISES
Program listing for exercise 3
Graphic for exercise 4
The Sine Function
Ÿ sin(x)

Ő
Ő 1 *******
Ő *** ***
Ő ** **
Ő **
Ő ** **
Ő **
Ő ** **
Ő** 2PIx
ņŐņņņņņņņ*ņņņņņņņŐņņņņņņņŐņņņņņņņŐņņņņņņņ*ņņņņņņņŐņņņņņņņŐņņņņņņņŐņņņņņņņ*ņņņņŹ
Ő **
Ő ** **
Ő **
Ő ** **
Ő **
Ő ** **
Ő *** ***
Ő -1 *******
Ő

×