Spec-Zone.ru › C++

Число с плавающей точкой

Число с плавающей точкой определяет константу времени компиляции, значение которой указано в исходном файле.

Синтаксис

последовательность_цифр десятичный_экспонент суффикс (необязательно) (1)
последовательность_цифр . десятичный_экспонент (необязательно) суффикс (необязательно) (2)
последовательность_цифр (необязательно) . последовательность_цифр десятичный_экспонент (необязательно) суффикс (необязательно) (3)
0x | 0X последовательность_шестнадцатеричных_цифр шестнадцатеричный_экспонент суффикс (необязательно) (4) (с C++17)
0x | 0X последовательность_шестнадцатеричных_цифр . шестнадцатеричный_экспонент суффикс (необязательно) (5) (с C++17)
0x | 0X последовательность_шестнадцатеричных_цифр (необязательно) . последовательность_шестнадцатеричных_цифр шестнадцатеричный_экспонент суффикс (необязательно) (6) (с C++17)
1) последовательность_цифр, представляющая целое число без разделителя десятичных знаков, в этом случае экспонента не является необязательной: 1e10, 1e-5L.
2) последовательность_цифр, представляющая целое число с разделителем десятичных знаков, в этом случае экспонента является необязательной: 1., 1.e-2.
3) последовательность_цифр, представляющая дробное число. Экспонента является необязательной: 3.14, .1f, 0.1e-1L.
4) Шестнадцатеричная последовательность_цифр, представляющая целое число без разделителя радикса. Экспонента никогда не является необязательной для шестнадцатеричных литералов с плавающей точкой: 0x1ffp10, 0X0p-1.
5) Шестнадцатеричная последовательность_цифр, представляющая целое число с разделителем радикса. Экспонента никогда не является необязательной для шестнадцатеричных литералов с плавающей точкой: 0x1.p0, 0xf.p-1.
6) Шестнадцатеричная последовательность_цифр, представляющая дробное число с разделителем радикса. Экспонента никогда не является необязательной для шестнадцатеричных литералов с плавающей точкой: 0x0.123p-1, 0xa.bp10l.

десятичный_экспонент имеет вид

e | E знак_экспоненты (необязательно) последовательность_цифр

шестнадцатеричный_экспонент имеет вид

p | P знак_экспоненты (необязательно) последовательность_цифр (с C++17)

знак_экспоненты, если присутствует, равен + или -

суффикс, если присутствует, представляет собой один из f, l, F, L, f16, f32, f64, f128, bf16, F16, F32, F64, F128, BF16(с C++23). Суффикс определяет тип литерала с плавающей точкой:

  • (без суффикса) определяет double
  • f F определяет float
  • l L определяет long double
  • f16 F16 определяет std::float16_t
  • f32 F32 определяет std::float32_t
  • f64 F64 определяет std::float64_t
  • f128 F128 определяет std::float128_t
  • bf16 BF16 определяет std::bfloat16_t
(с C++23)

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

(с C++14)

Объяснение

Используется десятичная экспоненциальная запись, что означает, что значение литерала с плавающей точкой — это мантисса, умноженная на число 10 в степени десятичный_экспонент. Например, математическое значение 123e4 равно 123×104.

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

Для шестнадцатеричного литерала с плавающей точкой мантисса интерпретируется как шестнадцатеричное рациональное число, а последовательность_цифр экспоненты интерпретируется как (десятичная) целая степень 2, в которой мантисса должна быть масштабирована.

double d = 0x1.4p3;// hex fraction 1.4 (decimal 1.25) scaled by 23, that is 10.0

(с C++17)

Примечания

Шестнадцатеричные литералы с плавающей точкой не были частью C++ до C++17, хотя они могут быть распарсены и напечатаны функциями ввода-вывода с C++11: оба потока ввода-вывода C++, когда std::hexfloat включен, и потоки ввода-вывода C: std::printf, std::scanf, и т. д. См. std::strtof для описания формата.

Макрос проверки функции Значение Std Функция
__cpp_hex_float 201603L (C++17) Шестнадцатеричные литералы с плавающей точкой

Пример

#include <iomanip>
#include <iostream>
#include <limits>
#include <typeinfo>
 
#define OUT(x) '\n' << std::setw(16) << #x << x
 
int main()
{
    std::cout
        << "Literal" "\t" "Printed value" << std::left
        << OUT( 58.            ) // double
        << OUT( 4e2            ) // double
        << OUT( 123.456e-67    ) // double
        << OUT( 123.456e-67f   ) // float, truncated to zero
        << OUT( .1E4f          ) // float
        << OUT( 0x10.1p0       ) // double
        << OUT( 0x1p5          ) // double
        << OUT( 0x1e5          ) // integer literal, not floating-point
        << OUT( 3.14'15'92     ) // double, single quotes ignored (C++14)
        << OUT( 1.18e-4932l    ) // long double
        << std::setprecision(39)
        << OUT( 3.4028234e38f  ) // float
        << OUT( 3.4028234e38   ) // double
        << OUT( 3.4028234e38l  ) // long double
        << '\n';
 
    static_assert(3.4028234e38f == std::numeric_limits<float>::max());
 
    static_assert(3.4028234e38f ==  // ends with 4
                  3.4028235e38f);   // ends with 5
 
    static_assert(3.4028234e38 !=   // ends with 4
                  3.4028235e38);    // ends with 5
 
    // Both floating-point constants below are 3.4028234e38
    static_assert(3.4028234e38f !=  // a float (then promoted to double)
                  3.4028234e38);    // a double
}

Возможный вывод:

Literal         Printed value
58.             58
4e2             400
123.456e-67     1.23456e-65
123.456e-67f    0
.1E4f           1000
0x10.1p0        16.0625
0x1p5           32
0x1e5           485
3.14'15'92      3.14159
1.18e-4932l     1.18e-4932
3.4028234e38f   340282346638528859811704183484516925440
3.4028234e38    340282339999999992395853996843190976512
3.4028234e38l   340282339999999999995912555211526242304

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2023):
    • 5.13.4 Литералы с плавающей точкой [lex.fcon]
  • Стандарт C++20 (ISO/IEC 14882:2020):
    • 5.13.4 Литералы с плавающей точкой [lex.fcon]
  • Стандарт C++17 (ISO/IEC 14882:2017):
    • 5.13.4 Литералы с плавающей точкой [lex.fcon]
  • Стандарт C++14 (ISO/IEC 14882:2014):
    • 2.14.4 Литералы с плавающей точкой [lex.fcon]
  • Стандарт C++11 (ISO/IEC 14882:2011):
    • 2.14.4 Литералы с плавающей точкой [lex.fcon]
  • Стандарт C++98 (ISO/IEC 14882:1998):
    • 2.13.3 Литералы с плавающей точкой [lex.fcon]

См. также

Пользовательские литералы(C++11) литералы с пользователем-определённым суффиксом
Документация C для Константа с плавающей точкой

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/floating_literal

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API