Рассматривать
float num;
cin >> num;
Хорошо ли определено, сколько символов ввода может потреблять этот код. Меня особенно интересует случай, когда входной поток может иметь num
указано с гораздо более высокой точностью, чем то, что float
Тип может представлять. Таким образом, в этом случае стандартизировано, будет ли код читать все это (вплоть до следующего нечислового ввода, но не включая его), или только до максимальной точности float
,
Смотрите информацию для «(1) арифметических типов» в std :: istream :: operator >> документы. Это использует num_get::get()
и соответствующая часть документов для этого гласит: «Функция прекращает чтение символов из последовательности, как только один символ не может быть частью действительного числового выражения».
Таким образом, из документации кажется, что все доступные цифры будут прочитаны, но они не будут все использоваться, если тип с плавающей точкой слишком «узок».
Входные данные определены в std :: num_get 22.4.2.1.2:
Этап 3: последовательность символов, накопленных на этапе 2 (поле)
конвертируется в числовое значение по правилам одной из функций
объявлено в шапке:— Для целочисленного значения со знаком — функция strtoll.
— Для целого числа без знака используется функция strtoull.
— Для значения с плавающей точкой функция strtold.
Числовое значение, которое будет сохранено, может быть одним из:
— ноль, если функция преобразования не может преобразовать все поле. ios_base :: failbit назначается для err.
— наиболее положительное представимое значение, если поле
представляет слишком большое положительное значение, чтобы быть представленным в val.
ios_base :: failbit назначается для err.— самое отрицательное представимое значение или ноль для целого типа без знака, если поле
представляет значение, слишком большое отрицательное, чтобы быть представленным в val.
ios_base :: failbit назначается для err.
Следовательно, поток будет использовать все допустимые шаблоны чисел (даже после переполнения), и состояние будет установлено соответствующим образом.
Вы можете проверить части этого с небольшим экспериментом:
#include <iostream>
int main(void) {
float f;
std::string s;
std::cin >> f;
std::cin >> s;
std::cout << f << std::endl;
std::cout << s << std::endl;
return 0;
}
Затем скомпилируйте:
$ g++ --version
g++ (GCC) 4.8.2
...
$ g++ -std=c++11 -pedantic -Wextra -Wall ./fltest.cpp
И запустить с вводом, который вы знаете, имеет больше цифр, чем float
имеет:
$ echo '3.1415926535 foo' | ./a.out
3.14159
foo
Таким образом, кажется, что посторонняя дополнительная точность отбрасывается (число с плавающей запятой одинарной точности имеет длину более 7 десятичных знаков точности).
Вы можете поиграть с точностью ввода и вывода, чтобы увидеть, какие эффекты они имеют, поставив, скажем:
std::cin.precision(7);
перед std::cin >> f;
линия или, скажем:
std::cout.precision(10);
перед std::cout << f;
линия.