Язык С допускает третий тип данных с плавающей запятой: long double. Цель этого типа — достижение большей точности, чем у типа double. Однако С гарантирует только то, что точность типа long double, по меньшей мере, не уступает точности типа double.
Объявление переменных с плавающей запятой
Переменные с плавающей занятой объявляются и инициализируются гой же самой манере, что и переменные целочисленных типов. Ниже приведено несколько примеров:
float noah, jonah;
double trouble;
float planck = 6.63e-34;
long double gnp;
Константы с плавающей запятой (литералы)
Записывать литеральную константу с плавающей запятой можно многими способами. Основная форма записи константы с плавающей запятой выглядит как последовательность цифр со знаком, включающая десятичную точку, за которой следует буква е или Е и экспонента со знаком, представляющая степень числа 10. Вот два примера допустимых констант с плавающей запятой:
-1.56Е + 12
2.87e-З
Знак “плюс” можно не указывать. Можно также опустить десятичную точку (2Е5) или экспоненциальную часть (19.28), но не то и другое одновременно. Можно обой-
102 Глава 3 тись без дробной части (З.Е16) или целой части (.45Е-6), но не без обоих компонентов сразу. Ниже показано еще несколько допустимых констант с плавающей запятой:
3.14159
.2
4е16
. 8Е-5
100.
Не применяйте пробелы в константах с плавающей запятой. Например, эта константа является недопустимой:
1.56 Е+12
По умолчанию компилятор предполагает, что константы с плавающей запятой имеют тип double. Предположим, например, что some является переменной типа float, и есть следующий оператор:
some = 4.0 * 2.0;
Тогда значения 4.0 и 2.0 сохраняются как данные типа double с использованием для каждого (обычно) 64 бита. Произведение вычисляется с применением арифметики с двойной точностью, и только после этого результат усекается к обычному типу float. Это гарантирует более высокую точность вычислений, но замедляет выполнение программы.
Язык С позволяет переопределить такое стандартное поведение компилятора за счет использования суффикса f или F, который заставляет компилятор трактовать константу с плавающей запятой как тип float, например, 2.3f и 9.11E9F. Суффикс 1 или L определяет число типа long double, например, 54.31 и 4.32e4L. Отметим, что букву L труднее перепугать с 1 (единица), чем букву 1. Если число с плавающей запятой не содержит суффикса, оно относится к типу double.
Начиная со стандарта С99, в языке С имеется новый формат для выражения констант с плавающей запятой. В нем применяется шестнадцатеричный префикс (0x или 0Х) с шестнадцатеричными цифрами, р или Р вместо е или Е и экспонента, которая является степенью 2, а не 10. Такое число может выглядеть следующим образом:
0xа.lfplO

Вывод значений с плавающей запятой
Функция printf() использует спецификатор формата %f для вывода чисел типа float и double в десятичном представлении и спецификатор %е для вывода в экспоненциальном представлении. Если ваша система поддерживает шестнадцатеричный формат чисел с плавающей запятой, то вместо е или Е можно применять а или А. Для вывода данных типа long double требуются спецификаторы %Lf, %Le и %La. Обратите внимание, что для вывода как float, так и double используется спецификатор %f, %е или %а. Причина в том, что язык С автоматически расширяет значения float до типа double, когда они передаются в качестве аргументов любой функции, такой как printf() , в прототипе которой тип аргумента не определен явным образом. Это поведение демонстрируется в листинге 3.7.
Данные в языке С 103
Листинг 3.7. Программа showf pt. с

Ниже приведен вывод, при условии, что компилятор совместим со стандартом С99/С11:
32000.000000 может быть записано как 3.200000е+04
И его 0xl.f4p+14 в шестнадцатеричной, представляющей степени 2, форме записи
2140000000.000000 может быть записано как 2.140000е+09
0.000053 может быть записано как 5.320000е — 05
Этот пример иллюстрирует стандартный вывод. В следующей главе мы обсудим, как управлять внешним видом вывода путем установки ширины поля и количества позиций справа от десятичной точки.
Переполнение и потеря значимости в операциях с плавающей запятой
Предположим, что наибольшее возможное значение типа float равно примерно 3.4Е38, и нужно выполнить следующие операции:
float toobig = 3.4Е38 * 100.0f;
printf("%e\n", toobig);
Читать дальше