Namespaces
Variants

Floating constant

From cppreference.net

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

Содержание

Синтаксис

Вещественная константа представляет собой не-lvalue выражение следующего вида:

significand exponent  (необязательно) suffix  (необязательно)

Где significand имеет вид

целая-часть  (необязательно) . (необязательно) дробная-часть  (необязательно)

Показатель степени имеет вид exponent

e | E знак-экспоненты  (необязательно) последовательность-цифр (1)
p | P знак-экспоненты  (необязательно) последовательность-цифр (2) (начиная с C99)
1) Синтаксис экспоненты для десятичной константы с плавающей точкой
2) Синтаксис экспоненты для шестнадцатеричной константы с плавающей точкой

Необязательные одинарные кавычки ( ' ) могут быть вставлены между цифрами в качестве разделителя, они игнорируются при компиляции.

(начиная с C23)

Объяснение

Если significand начинается с последовательности символов 0x или 0X , то плавающая константа является шестнадцатеричной плавающей константой . В противном случае это десятичная плавающая константа .

Для шестнадцатеричной плавающей константы , significand интерпретируется как шестнадцатеричное рациональное число, а digit-sequence экспоненты интерпретируется как целая степень числа 2, на которую должен быть масштабирован significand.

double d = 0x1.2p3; // hex fraction 1.2 (decimal 1.125) scaled by 2^3, that is 9.0
(since C99)

Для десятичной плавающей константы significand интерпретируется как десятичное рациональное число, а digit-sequence экспоненты интерпретируется как целая степень 10, на которую должна быть масштабирована significand.

double d = 1.2e3; // десятичная дробь 1.2, умноженная на 10^3, то есть 1200.0

Суффиксы

Несуффиксированная плавающая константа имеет тип double . Если суффикс представляет собой букву f или F , плавающая константа имеет тип float . Если суффикс представляет собой букву l или L , плавающая константа имеет тип long double .

Если реализация предопределяет макрос __STDC_IEC_60559_BFP__ , дополнительно поддерживаются следующие суффиксы и соответствующие плавающие константы:

  • если суффикс равен df или DF , плавающая константа имеет тип _Decimal32 ;
  • если суффикс равен dd или DD , плавающая константа имеет тип _Decimal64 ;
  • если суффикс равен dl или DL , плавающая константа имеет тип _Decimal128 .

Суффиксы для десятичных плавающих типов не допускаются в шестнадцатеричных плавающих константах.

(начиная с C23)

Необязательные части

Если экспонента присутствует и дробная часть не используется, десятичный разделитель может быть опущен:

double x = 1e0; // число с плавающей точкой 1.0 (точка не используется)

Для десятичных плавающих констант экспоненциальная часть является необязательной. Если она опущена, точка не является необязательной, и должна присутствовать либо целая часть , либо дробная часть .

double x = 1.; // число с плавающей точкой 1.0 (дробная часть необязательна)
double y = .1; // число с плавающей точкой 0.1 (целая часть необязательна)

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

(since C99)

Представимые значения

Результат вычисления плавающей константы представляет собой либо ближайшее представимое значение, либо большее/меньшее представимое значение, непосредственно прилегающее к ближайшему представимому значению, выбранное определяемым реализацией способом (другими словами, направление округления по умолчанию во время трансляции определяется реализацией).

Все вещественные константы одинаковой исходной формы преобразуются в один и тот же внутренний формат с одинаковым значением. Вещественные константы разных исходных форм, например 1.23 и 1.230 , не обязаны преобразовываться в одинаковый внутренний формат и значение.

Константы с плавающей точкой могут преобразовываться к большему диапазону и точности, чем указано их типом, если это определено FLT_EVAL_METHOD . Например, константа 0.1f может вести себя как 0.1L в выражении.

Результат вычисления шестнадцатеричной константы с плавающей точкой, если FLT_RADIX равен 2, представляет собой точное значение, представленное константой с плавающей точкой, корректно округленное к целевому типу.

(начиная с C99)

Десятичные плавающие константы, которые имеют одинаковое числовое значение x но разные квантовые экспоненты, например 1230 . dd , 1230.0dd , и 1.23e3dd , имеют различимые внутренние представления.

Квантовая экспонента q десятичной плавающей константы определяется таким образом, что 10 q
представляет 1 в позиции последней цифры significand , когда это возможно. Если квантовая экспонента q и коэффициент c=x·10 -q
, определенные выше, не могут быть точно представлены в типе плавающей константы, q увеличивается по мере необходимости в пределах ограничений типа, а c соответствующим образом уменьшается с необходимым округлением. Округление может привести к нулю или бесконечности. Если (возможно округленный) c все еще выходит за пределы допустимого диапазона после того, как q достигает максимального значения, результирующая плавающая константа имеет значение положительной бесконечности.

(since C23)

Примечания

По умолчанию направление округления и точность действуют при преобразовании плавающих констант во внутренние представления, и исключения с плавающей точкой не возбуждаются, даже если #pragma STDC FENV_ACCESS действует (для преобразования строк символов во время выполнения strtod может быть использована). Обратите внимание, что это отличается от арифметических константных выражений плавающего типа.

Буквы в плавающих константах нечувствительны к регистру , за исключением того, что прописные и строчные буквы нельзя одновременно использовать в суффиксах для десятичных типов с плавающей точкой (since C23) : 0x1 . ep + 3 и 0X1 . EP + 3 представляют одно и то же значение с плавающей точкой 15.0 .

Десятичная точка, указанная с помощью setlocale не влияет на синтаксис плавающих констант: символ десятичной точки всегда является точкой.

В отличие от целых чисел, не каждое значение с плавающей точкой может быть представлено непосредственно десятичной или даже шестнадцатеричной (since C99) синтаксической константой : макросы NAN и INFINITY а также функции такие как nan предоставляют способы генерации этих специальных значений (since C99) . Обратите внимание, что 0x1 . FFFFFEp128f , который может казаться NaN для IEEE float, на самом деле переполняется до бесконечности в этом формате.

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

Пример

#include <stdio.h>
int main(void)
{
    printf("15.0     = %a\n", 15.0);
    printf("0x1.ep+3 = %f\n", 0x1.ep+3);
    // Константы вне диапазона типа double.
    printf("+2.0e+308 --> %g\n",  2.0e+308);
    printf("+1.0e-324 --> %g\n",  1.0e-324);
    printf("-1.0e-324 --> %g\n", -1.0e-324);
    printf("-2.0e+308 --> %g\n", -2.0e+308);
}

Вывод:

15.0     = 0x1.ep+3
0x1.ep+3 = 15.000000
+2.0e+308 --> inf
+1.0e-324 --> 0
-1.0e-324 --> -0
-2.0e+308 --> -inf

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 6.4.4.2 Вещественные константы (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 6.4.4.2 Вещественные константы (стр: 47-48)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 6.4.4.2 Вещественные константы (стр: 65-66)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 6.4.4.2 Вещественные константы (стр. 57-58)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 3.1.3.1 Вещественные константы

Смотрите также

C++ documentation для Floating-point literal