Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Рассмотрим целочисленную задачу.

short int y = 40000;

int i = 1000000;

cout << y << " " << i*i << "\n";

Выполнив эту программу, получим следующий результат:

–25536 –727379968

Этого следовало ожидать. Здесь мы видим эффект переполнения. Целочисленные типы позволяют представить лишь относительно небольшие целые числа. Нам просто не хватит битов, чтобы точно представить каждое целое число, поэтому нам необходим способ, позволяющий выполнять эффективные вычисления. В данном случае двухбайтовое число типа

short
не может представить число 40 000,
а четырехбайтовое число типа
int
не может представить число 1 000 000 000 000. Точные размеры встроенных типов в языке C++ (см. раздел A.8) зависят от аппаратного обеспечения и компилятора; размер переменной
x
или типа
x
в байтах можно определить с помощью оператора
sizeof(x)
. По определению
sizeof(char)==1
. Это можно проиллюстрировать следующим образом.

Эти размеры характерны для операционной системы Windows и компилятора компании Microsoft. В языке С++ есть много способов представить целые числа и числа с плавающей точкой, используя разные размеры, но при отсутствии важных причин лучше придерживаться типов
char
,
int
и
double
. В большинстве программ (но, разумеется, не во всех) остальные типы целых чисел и чисел с плавающей точкой вызывают больше проблем, чем хотелось бы.

Целое число можно присвоить переменной, имеющей тип числа с плавающей точкой. Если целое число окажется больше, чем может представить тип числа с плавающей точкой, произойдет потеря точности. Рассмотрим пример.

cout << "размеры: " << sizeof(int) << ' ' << sizeof(float) << '\n';

int x = 2100000009; // большое целое число

float f = x;

cout << x << ' ' << f << endl;

cout << setprecision(15) << x << ' ' << f << '\n';

На нашем компьютере мы получили следующий результат:

Sizes: 4 4

2100000009 2.1e+009

2100000009 2100000000

Типы

float
и
int
занимают одинаковое количество памяти (4 байта). Тип
float
состоит из мантиссы (как правило, числа от нуля до единицы) и показателя степени (т.е. мантисса*10 показатель степени), поэтому он не может точно выразить самое большое число
int
. (Если бы мы попытались сделать это, то не смогли бы выделить достаточно памяти для мантиссы после размещения в памяти показателя степени.) Как и следовало ожидать, переменная
f
представляет число 2100000009 настолько точно, насколько это возможно. Однако последняя цифра
9
вносит слишком большую ошибку, — именно поэтому мы выбрали это число для иллюстрации.

С другой стороны, когда мы присваиваем число с плавающей точкой перемен- ной целочисленного типа, происходит усечение; иначе говоря, дробная часть — цифры после десятичной точки — просто отбрасываются. Рассмотрим пример.

float f = 2.8;

int x = f;

cout << x << ' ' << f << '\n';

Значение переменной

x
будет равно
2
. Оно не будет равным
3
, как вы могли подумать, если применили “правило округления 4/5”. В языке C++ преобразование типа
float
в тип
int
сопровождается усечением, а не округлением.

При вычислениях следует опасаться возможного переполнения и усечения.

Язык C++ не решит эту проблему за вас. Рассмотрим пример.

void f(int i, double fpd)

{

char c = i; // да: тип char действительно представляет

// очень маленькие целые числа

short s = i; // опасно: переменная типа int может

// не поместиться

// в памяти, выделенной для переменной

// типа short

i = i+1; // что, если число i станет максимальным?

long lg = i*i; // опасно: переменная типа long не может

// вместить результат

float fps = fpd; // опасно: большее число типа large может

// не поместиться в типе float

i = fpd; // усечение: например, 5.7 –> 5

fps = i; // можно потерять точность (при очень

// больших целых)

}

void g

{

char ch = 0;

for (int i = 0; i<500; ++i)

cout << int(ch++) << '\t';

}

Если сомневаетесь, поэкспериментируйте! Не следует отчаиваться и в то же время нельзя просто читать документацию. Без экспериментирования вы можете не понять содержание весьма сложной документации, связанной с числовыми типами.

ПОПРОБУЙТЕ

Выполните функцию

g
. Модифицируйте функцию
f
так, чтобы она выводила на печать переменные
c
,
s
,
i
и т.д. Протестируйте программу на разных значениях.

Представление целых чисел и их преобразование еще будет рассматриваться в разделе 25.5.3. По возможности ограничивайтесь немногими типами данных, чтобы минимизировать вероятность ошибок. Например, используя только тип
double
и избегая типа
float
, мы минимизируем вероятность возникновения проблем, связанных с преобразованием
double
float
. Например, мы предпочитаем использовать только типы
int
,
double
и
complex
(см. раздел 24.9) для вычислений,
char
— для символов и
bool
— для логических сущностей. Остальные арифметические типы мы используем только при крайней необходимости.

24.2.1. Пределы числовых диапазонов

Каждая реализация языка C++ определяет свойства встроенных типов в заголовках
<limits>
,
<climits>
и
<limits.h>
, чтобы программисты могли проверить пределы диапазонов, установить сигнальные метки и т.д. Эти значения перечислены в разделе Б.9.1. Они играют очень важную роль для создания низкоуровневых инструментов. Если они вам нужны, значит, вы работаете непосредственно с аппаратным обеспечением, хотя существуют и другие приложения. Например, довольно часто возникают вопросы о тонкостях реализации языка, например: “Насколько большим является тип
int
?” или “Имеет ли знак тип
char
?” Найти определенные и правильные ответы в системной документации бывает трудно, а в стандарте указаны только минимальные требования. Однако можно легко написать программу, находящую ответы на эти вопросы.

Поделиться:
Популярные книги

Мимик!

Северный Лис
1. Сбой Системы!
Фантастика:
боевая фантастика
5.40
рейтинг книги
Мимик!

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Я Гордый Часть 3

Машуков Тимур
3. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый Часть 3

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

Счастливый торт Шарлотты

Гринерс Эва
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Счастливый торт Шарлотты

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Неверный. Свободный роман

Лакс Айрин
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Неверный. Свободный роман

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Темный Лекарь 4

Токсик Саша
4. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 4

Сердце Дракона. Предпоследний том. Часть 1

Клеванский Кирилл Сергеевич
Сердце дракона
Фантастика:
фэнтези
5.00
рейтинг книги
Сердце Дракона. Предпоследний том. Часть 1

Курсант: Назад в СССР 10

Дамиров Рафаэль
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 10