Перейти к содержимому

Сколько байт занимает float

  • автор:

1.2.3. Данные плавающего типа

Для переменных, представляющих число с плавающей точкой используются следующие модификаторы-типа : float, double, long double (в некоторых реализациях языка long double СИ отсутствует).

Величина с модификатором-типа float занимает 4 байта. Из них 1 байт отводится для знака, 8 бит для избыточной экспоненты и 23 бита для мантиссы. Отметим, что старший бит мантиссы всегда равен 1, поэтому он не заполняется, в связи с этим диапазон значений переменной с плавающей точкой приблизительно равен от 3.14E-38 до 3.14E+38.

Величина типа double занимает 8 бит в памяти. Ее формат аналогичен формату float. Биты памяти распределяются следующим образом: 1 бит для знака, 11 бит для экспоненты и 52 бита для мантиссы. С учетом опущенного старшего бита мантиссы диапазон значений равен от 1.7E-308 до 1.7E+308.

float f, a, b; double x,y;

2 thoughts on “1.2.3. Данные плавающего типа”

zzzzzzzzzzz :
Опечатка:
Из них 1 байт отводится для знака
—>
бит
zzzzzzzzzzz :

Разрешите ещё немного попридираться, я из хороших побуждений. Величина типа double занимает 8 бит
—>
байт

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Рубрики

  • ARM. Учебный курс
  • AVR. Учебный курс
  • MegaHard Lab
  • MSP430. Учебный курс
  • Автоэлектроника
  • Готовые устройства
  • Диагностика и ремонт
  • Инструмент
  • Книги
  • Начинающим
  • Новости
  • Радиолюбительские Технологии
  • Робототехника
  • Софт

Карта людей сообщества

Типы данных в языке C++

Для вывода на консоль символов wchar_t следует использовать не std::cout, а поток std::wcout. При этом поток std::wcout может работать как с char, так и с wchar_t. А поток std::cout для переменной wchar_t вместо символа будет выводить его числовой код.

В стандарте С++11 были добавлены типы char16_t и char32_t, которые ориентированы на использование Unicode. Однако на уровне ОС пока не реализованы потоки для работы с этими типами. Поэтому если потребуется вывести на консоль значения переменных этих типов, то необходимо преобразовать переменные к типам char или wchar_t.

Стандарт устанавливает лишь минимальные значения размера, который тип занимает в памяти. Например, для типов int и short минимальное значение — 16 бит, для типа long — 32 бита. При этом размер типа long должен быть не меньше размера типа int, а размер типа int — не меньше размера типа short, а размер типа long double должен быть больше double. Для определения точного размера определенного типа в С++ есть оператор sizeof(), который возвращает размер памяти в байтах, которую занимает переменная.

Преобразование типов

Преобразование типов происхоит когда требуется конвертация значений из одного типа данных в другой. Преобразование типов может происходить в следующих случаях:

  • присваивание или инициализация переменной
  • передача значений в функцию
  • возврат значения из функции
  • вычисление арифметических выражений

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

Неявное преобразование типов

Преобразование, когда значение из одного типа конвертируется в другой тип, большего размера, называется числовым расширением и всегда безопасно и не приводит к потере данных.

Когда значение типа данных конвертируется в аналогичный, но меньший по размеру тип данных, или конвертация происходит между разными типами данных, то это называется числовой конверсией и может (но не всегда) приводить к потере данных.

Арифметические выражения

При обработке выражений компилятор разбивает каждое выражение на отдельные подвыражения. Арифметические операторы требуют, чтобы их операнды были одного типа данных. Чтобы это гарантировать, компилятор использует следующие правила:

  • если операндом является целое число меньше (по размеру/диапазону) типа int, то оно подвергается интегральному расширению в int или в unsigned int
  • если операнды разных типов данных, то компилятор вычисляет операнд с наивысшим приоритетом и неявно конвертирует тип другого операнда в такой же тип, как у первого

Приоритет типов операндов для арифметических операций:

  • long double (самый высокий);
  • double
  • float
  • unsigned long long
  • long long
  • unsigned long
  • long
  • unsigned int
  • int (самый низкий)

Явное преобразование типов

В языке C++ есть 5 видов операций явного преобразования типов:

  • конвертация в стиле языка C
  • использование операции static_cast
  • использование операции dynamic_cast
  • использование операции const_cast
  • использование операции reinterpret_cast
Конвертация в стиле языка C

В программировании на языке Cи явное преобразование типов данных выполняется с помощью оператора ( ).

int i1 = 11; int i2 = 3; float x = (float)i1 / i2;

Язык C++ также позволяет использовать этот оператор следующим образом:

int i1 = 11; int i2 = 3; float x = float(i1) / i2;

Конвертация в стиле языка C не проверяется компилятором, поэтому она может быть неправильно использована, например привести к переполнению.

Операция static_cast

static_castтип>(выражение)

Операция static_cast в языке C++ осуществляет явное и допустимое приведение заданного выражения в указанный тип данных. Операция static_cast аналогична операции «круглые скобки» с одним исключением: она не выполняет приведение указателей на неродственные типы (для этого применяется операция reinterpret_cast). Основным преимуществом операции static_cast является проверка выполнения компилятором во время компиляции с генерацией предупреждений, что усложняет возможность возникновения ошибок.

int i1 = 11; int i2 = 3; float x = static_cast(i1) / i2;
Операция dynamic_cast

dynamic_castтип>(указатель/ссылка)

В языке C++ операция dynamic_cast используется для конвертации указателей родительского класса в указатели дочернего класса. Это является наиболее распространенным применением оператора dynamic_cast.Этот процесс называется приведением к дочернему типу (или «понижающим приведением типа»).

Если dynamic_cast не может выполнить конвертацию, то он возвращает нулевой указатель, поэтому нужно делать проверку результата динамического приведения на нулевой указатель. Оператор dynamic_cast также может использоваться и со ссылками. Работа dynamic_cast со ссылками аналогична работе с указателями, но поскольку в языке C++ не существует «нулевой ссылки», то dynamic_cast не может возвратить «нулевую ссылку» при сбое. Вместо этого dynamic_cast генерирует исключение типа std::bad_cast.

Поскольку динамическое приведение выполняет проверку во время работы программы, использование оператора dynamic_cast немного снижает производительность. Понижающее приведение также может быть выполнено и через оператор static_cast. Основное отличие заключается в том, что static_cast не выполняет проверку во время запуска программы. Это позволяет оператору static_cast быть быстрее, но опаснее оператора dynamic_cast.

Существуют случаи, в которых понижающее приведение с использованием оператора dynamic_cast не работает:

  • Наследование типа private или типа protected
  • Классы, которые не объявляют или не наследуют классы с какими-либо виртуальными функциями (и, следовательно, не имеют виртуальных таблиц)
  • Случаи, связанные с виртуальными базовыми классами

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

  • Если нет возможности изменить родительский класс, чтобы добавить в него свою виртуальную функцию (например, если родительский класс является частью Стандартной библиотеки С++)
  • Если требуется доступ к чему-либо, что есть только в дочернем классе (например к функции, которая существует только в дочернем классе)
  • Если добавление виртуальной функции в родительский класс не имеет смысла. В таком случае, в качестве альтернативы, если не нужно создавать объект родительского класса, можно использовать чистую виртуальную функцию
Parent *p = getParentObject(); Child *ch = dynamic_cast(p);
Операция const_cast

const_castтип>(указатель/ссылка)

Операция const_cast используется для снятия/установки модификаторов const, volatile, mutable. Часто это применяется, чтобы обойти неудачную архитектуру программы или библиотеки, для стыковки С и С++, для передачи информации через обобщённые указатели void*, для одновременного написания const- и не-const-версии функции.

Операцию const_cast для сброса const следует использовать только в крайних случаях, когда точно известно поведение программы. А вот использование операции const_cast ради добавления константности можно использовать без опасений получить неопределенное поведение.

При использовании операции const_cast выражение должно быть ссылкой или указателем, а тип должен совпадать с исходным типом вплоть до модификаторов const, volatile и mutable.

void foo(char*)<> int main() < char const* str = ""; foo(const_cast(str)); //снятие константности позволяет использовать функцию >
Операция reinterpret_cast

reinterpret_castтип>(выражение)

Оператор приведения reinterpret_cast используется для приведения несовместимых типов с сохранением битового представления. Может приводить целое число к указателю, указатель к целому числу, указатель к указателю (это же касается и ссылок).

Является функционально усеченным аналогом приведения типов в стиле языка С.

Отличие состоит в том, что reinterpret_cast не может снимать квалификаторы const и volatile, а также не может делать небезопасное приведение типов не через указатели, а напрямую по значению. Например, переменную типа int к переменной типа double привести при помощи reinterpret_cast нельзя.

Ограничения на тип>:

  • Если выражение> — это значение порядкового типа или указатель, то тип> может быть порядковым типом или указателем
  • Если выражение> — это ссылка, то тип> должен быть ссылкой
int i; char *p = "Это строка"; i = reinterpret_cast(p); // Приведение указателя к целому числу

Сколько байт занимает float

Требования к объему памяти для столбцов каждого типа, поддерживаемого MySQL, перечислены ниже по категориям.

Требования к памяти для числовых типов

Тип столбца Требуемая память
TINYINT 1 byte
SMALLINT 2 байта
MEDIUMINT 3 байта
INT 4 байта
INTEGER 4 байта
BIGINT 8 байтов
FLOAT(X) 4, если X
FLOAT 4 байта
DOUBLE 8 байтов
DOUBLE PRECISION 8 байтов
REAL 8 байтов
DECIMAL(M,D) M+2 байт, если D > 0, M+1 байт, если D = 0 ( D +2, если M < D )
NUMERIC(M,D) M+2 байт, если D > 0, M+1 байт, если D = 0 ( D +2, если M < D )

Требования к памяти для типов даты и времени

Тип столбца Требуемая память
DATE 3 байта
DATETIME 8 байтов
TIMESTAMP 4 байта
TIME 3 байта
YEAR 1 байт

Требования к памяти для символьных типов

Тип столбца Требуемая память
CHAR(M) M байт, 1
VARCHAR(M) L +1 байт, где L <= M и 1
TINYBLOB , TINYTEXT L +1 байт, где L < 2^8
BLOB , TEXT L +2 байт, где L < 2^16
MEDIUMBLOB , MEDIUMTEXT L +3 байт, где L < 2^24
LONGBLOB , LONGTEXT L +4 байт, где L < 2^32
ENUM(‘value1′,’value2’. ) 1 или 2 байт, в зависимости от количества перечисляемых величин (максимум 65535)
SET(‘value1′,’value2’. ) 1, 2, 3, 4 или 8 байт, в зависимости от количества элементов множества (максимум 64)

VARCHAR , BLOB и TEXT являются типами данных с переменной длиной строки, для таких типов требования к памяти в общем случае определяются реальным размером величин в столбце (представлен символом L в приведенной выше таблице), а не максимально возможным для данного типа размером. Например, столбец VARCHAR(10) может содержать строку с максимальной длиной 10 символов. Реально требуемый объем памяти равен длине строки ( L ) плюс 1 байт для записи длины строки. Для строки ‘abcd’ L равно 4 и требуемый объем памяти равен 5 байтов.

В случае типов данных BLOB и TEXT требуется 1, 2, 3 или 4 байта для записи длины значения данного столбца в зависимости от максимально возможной длины для данного типа. See section 6.2.3.2 Типы данных BLOB и TEXT .

Если таблица включает в себя столбец какого-либо типа с переменной длиной строки, то формат записи также будет переменной длины. Следует учитывать, что при создании таблицы MySQL может при определенных условиях преобразовать тип столбца с переменной длиной в тип с постоянной длиной строки или наоборот. See section 6.5.3.1 Молчаливые изменения определений столбцов.

Размер объекта ENUM определяется количеством различных перечисляемых величин. Один байт используется для перечисления до 255 возможных величин. Используя два байта, можно перечислить до 65535 величин. See section 6.2.3.3 Тип перечисления ENUM .

Размер объекта SET определяется количеством различных элементов множества. Если это количество равно N , то размер объекта вычисляется по формуле (N+7)/8 и полученное число округляется до 1 , 2 , 3 , 4 или 8 байтов. Множество SET может иметь максимум 64 элемента. See section 6.2.3.4 Тип множества SET .

Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

5d1610911369c751179657.png

Например,int занимает 4 байта,из-за этого,работая с этим типом данных,мы можем работать только с ограниченными по величине цифрами.Но в случае с double можно задать абсолютно любое число,да еще и указать множество цифр после запятой.Как это работает?
И еще,пользуясь случаем,хочу спросить: для чего в конце приписывают ‘f’ ,когда пользуются типом данных float?

  • Вопрос задан более трёх лет назад
  • 3871 просмотр

Комментировать
Решения вопроса 1
Программист на «си с крестами» и не только

Например, int занимает 4 байта

По современному консенсусу, да. Но иногда может занимать 2 байта (меньше — вроде нет).

В случае с double можно задать абсолютно любое число

double x = 1e500;
Ответ статического анализатора Clang: magnitude of floating-point constant is too large for type ‘double’; maximum is 1.79…E+308

На число 1.23456789012345678901234 не жалуется, но учите матчасть — относительная точность double 52 двоичных цифры (исключая головную единицу), или около 16 десятичных.

для чего в конце приписывают ‘f’ ,когда пользуются типом данных float?

Чтобы расчёт float x; return x + 12.34f вёлся в менее точном типе float, а не double.
А вот коду float x = 12.34; это совершенно не нужно, компилятор и сам поймёт, что преобразование double → float можно сделать при компиляции.

Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

Зависит от машины, но по выработанному консенсусу — float 4, double 8.
Нестандартная (присущая x86) реализация long double имеет 10 значащих байтов, но 12 или 16 вместе с выравниванием.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *