Сколько памяти занимает float
В С++ существуют два типа данных с плавающей точкой: float и double . Типы данных с плавающей точкой предназначены для хранения чисел с плавающей точкой. Типы данных float и double могут хранить как положительные, так и отрицательные числа с плавающей точкой. У типа данных float размер занимаемой памяти в два раза меньше, чем у типа данных double , а значит и диапазон принимаемых значений тоже меньше. Если тип данных float объявить с приставкой long , то диапазон принимаемых значений станет равен диапазону принимаемых значений типа данных double . В основном, типы данных с плавающей точкой нужны для решения задач с высокой точностью вычислений, например, операции с деньгами.
Как хранятся действительные числа в компьютере
Для хранения действительных чисел в памяти компьютера отводится определённое количество бит. Действительное число хранится в виде знака (плюс или минус), мантиссы и экспоненты. Что такое мантисса и экспонента лучше объяснить на примере: масса Земли равна 5.972*10 24 килограмм. Здесь 5.972 — мантисса, а 24 — экспонента.
При выводе больших (или очень маленьких) чисел в программе на C++ можно увидеть на экране запись типа 5.972E23. Сначала выводится мантисса, затем — буква E, а затем — экспонента. Запись представлена в десятичной системе счисления. В таком же формате можно вводить большие или очень маленькие действительные числа. Этот формат называется экспоненциальной записью числа.
Мы будем работать с типом double (с числами двойной точности), который занимает 8 байт. Один бит отводится под знак числа, 11 под экспоненту и 52 под мантиссу. С помощью 52 бит можно хранить числа длиной до 15-16 десятичных цифр. Таким образом, независимо от того, какая у числа экспонента, правильные значения будут иметь только первые 15 цифр. В примере с массой Земли точно заданы первые 4 цифры, таким образом, погрешность составляет 10 20 килограмм. Это довольно большая погрешность. Чтобы масса Земли с точностью до первых четырёх знаков изменилась, на неё нужно дополнительно поселить миллиард миллиардов довольно упитанных людей.
Таким образом, можно сказать, что числа в компьютере хранятся не с абсолютной, а с относительной погрешностью (то есть погрешность зависит от значения хранимого числа).
То, что числа хранятся неточно, создаёт нам множество проблем.
Итак, мы рассмотрели главные моменты, касающиеся основных типов данных в С++. Осталось только показать, откуда взялись все эти диапазоны принимаемых значений и размеры занимаемой памяти. А для этого разработаем программу, которая будет вычислять основные характеристики всех, выше рассмотренных, типов данных.
Тем не менее, эта аналогия не совсем подходит к программированию, так как переменные могут занимать больше 1 байта памяти. Следовательно, одна переменная может использовать 2, 4 или даже 8 последовательных адресов. Объем памяти, который использует переменная, зависит от типа данных этой переменной. Так как мы, как правило, получаем доступ к памяти через имена переменных, а не через адреса памяти, то компилятор может скрывать от нас все детали работы с переменными разных размеров.
Есть несколько причин по которым полезно знать, сколько памяти занимает определенная переменная/тип данных.
Во-первых, чем больше она занимает, тем больше информации сможет хранить. Так как каждый бит содержит либо 0 , либо 1 , то 1 бит может иметь 2 возможных значения.
2 бита могут иметь 4 возможных значения:
бит 0 | бит 1 |
0 | 0 |
0 | 1 |
1 | 0 |
1 | 1 |
3 бита могут иметь 8 возможных значений:
бит 0 | бит 1 | бит 2 |
0 | 0 | 0 |
0 | 0 | 1 |
0 | 1 | 0 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 0 | 1 |
1 | 1 | 0 |
1 | 1 | 1 |
По сути, переменная с n-ным количеством бит может иметь 2 n возможных значений. Поскольку байт состоит из 8 бит, то он может иметь 2 8 (256) возможных значений.
Размер переменной накладывает ограничения на количество информации, которую она может хранить. Следовательно, переменные, которые используют больше байт, могут хранить более широкий диапазон значений.
Размер основных типов данных в C++
Язык C++ гарантирует только их минимальный размер:
Тип | Минимальный размер | |
Логический тип данных | bool | 1 байт |
Символьный тип данных | char | 1 байт |
wchar_t | 1 байт | |
char16_t | 2 байта | |
char32_t | 4 байта | |
Целочисленный тип данных | short | 2 байта |
int | 2 байта | |
long | 4 байта | |
long long | 8 байт | |
Тип данных с плавающей запятой | float | 4 байта |
double | 8 байт | |
long double | 8 байт |
Фактический размер переменных может отличаться на разных компьютерах, поэтому для его определения используют оператор sizeof.
Оператор sizeof — это унарный оператор, который вычисляет и возвращает размер определенной переменной или определенного типа данных в байтах. Вы можете скомпилировать и запустить следующую программу, чтобы выяснить, сколько занимают разные типы данных на вашем компьютере:
Я в последнее время немного затупил, не мог вспомнить, сколько байт занимает тип double в AVR-GCC. Обычно при программировании контроллеров работаешь с целочисленными типами, типа int и char, а к типам с плавающей точкой прибегаешь не часто, в связи с их ресурсоемкостью.
Поэтому, на будущее, оставлю себе здесь памятку с указанием размеров занимаемой памяти типами данных для компилятора AVR-GCC и диапазон изменения переменных этого типа.
Типы данных в языке Си для компилятора AVR-GCC
Тип | Размер в байтах (битах) | Интервал изменения |
---|---|---|
char | 1 (8) | -128 .. 127 |
unsigned char | 1 (8) | 0 .. 255 |
signed char | 1 (8) | -128 .. 127 |
int | 2 (16) | -32768 .. 32767 |
unsigned int | 2 (16) | 0 .. 65535 |
signed int | 2 (16) | -32768 .. 32767 |
short int | 2 (16) | -32768 .. 32767 |
unsigned short int | 2 (16) | 0 .. 65535 |
signed short int | 2 (16) | -32768 .. 32767 |
long int | 4 (32) | -2147483648 .. 2147483647 |
unsigned long int | 4 (32) | 0 .. 4294967295 |
signed long int | 4 (32) | -2147483648 .. 2147483647 |
float | 4 (32) | 3.4Е-38 .. 3.4Е+38 |
double | 4 (32) | 3.4Е-38 .. 3.4Е+38 |
long double | 10 (80) | 3.4Е-4932 .. 3.4Е+4932 |
В дополнение к этому, в библиотеках AVR-GCC введено несколько производных от стандартных типов. Они описаны в файле stdint.h. Сделано это, наверно, для улучшения наглядности и уменьшения текста программ (ускорения их написания :)). Вот табличка соответствия:
Производные типы от стандартных в языке Си для компилятора AVR-GCC
Производный тип | Стандартный тип |
---|---|
int8_t | signed char |
uint8_t | unsigned char |
int16_t | signed int |
uint16_t | unsigned int |
int32_t | signed long int |
uint32_t | unsigned long int |
int64_t | signed long long int |
uint64_t | unsigned long long int |
Тип Void
В школе на уроках физики изучают, как записывать числа «в стандартном виде»:
[math]x = m \cdot 10^n[/math] ,
[math]1 \le m \lt 10,\:n\in\mathbb[/math] .
Число [math]m[/math] называют мантиссой, число [math]p[/math] называют порядком.
В компьютере в качестве основания вместо числа [math]10[/math] используется число [math]2[/math] .
Стандарт IEEE 754
IEEE 754 (IEC 60559) — широко используемый стандарт IEEE, описывающий формат представления чисел с плавающей точкой.
binary32 | binary64 | |
---|---|---|
Название | число одинарной точности | число двойной точности |
Тип в C | float | double |
Биты знака | 1 | 1 |
Биты экспоненты | 8 | 11 |
Биты мантиссы | 23 | 52 |
Мин. положит. денорм. значение | [math]1.401298464 \times 10^[/math] | [math]4.9406564584124654 \times 10^[/math] |
Макс. значение | [math]3.402823 \times 10^[/math] | [math]1.7976931348623157 \times 10^[/math] |
Число десятичных цифр | 7—8 | 15—17 |
Стандартом языка C гарантируется только, что
На большинстве платформ применяются типы с плавающей точкой в соответствии со стандартом IEEE 754.
Важным нюансом является форма записи вещественных констант разных типов. Например,
- 1 — это константа типа int,
- 1. или 1.0 — это константа типа double,
- 1.f или 1.0f — это константа типа float.
На следующих занятиях мы разберём, почему смешивать в одном выражении операнды типов float и double может быть плохо.
Представление в памяти
- знак числа
- экспонента (показатель)
- мантисса
Число одинарной точноcти (float)
Занимает в памяти 32 бита (4 байта).
Числа одинарной точности с плавающей запятой обеспечивают относительную точность 7-8 десятичных цифр в диапазоне от 10 −38 до примерно 10 38 .
[math](-1)^> \times (1.b_b_ \dots b_0)_2 \times 2^<(b_<30>b_ \dots b_)_2 - 127>[/math]
Число двойной точноcти (double)
Занимает в памяти 64 бита (8 байт).
Числа двойной точности с плавающей запятой обеспечивают точность в 15—17 десятичных цифр и масштабы в диапазоне примерно от 10 −308 до 10 308 .
Распределение
Множество вещественных чисел в математике бесконечно и даже несчётно.
Множество чисел, представимых в формате с плавающей точкой, не только счётно, но и конечно. Все эти числа являются рациональными.
Однако расстояние между соседними числами непостоянно.
Промежуток между соседними числами удваивается при переходе через каждую степень двойки.
Чем дальше от нуля, тем реже и реже встречаются на числовой прямой числа, которые представимы вещественным типом.
Точное представление
Точно представляются только несократимые дроби, у которых знаменатель является степенью двойки.
Читайте также: