考虑
float num;
cin >> num;
是否明确定义了此代码可以使用多少个输入字符。我对输入流的指定精度可能比类型可以表示num
的精度高得多的情况特别感兴趣。float
因此,在这种情况下,代码是否会读取所有代码(直到但不包括下一个非数字输入)或仅读取float
.
考虑
float num;
cin >> num;
是否明确定义了此代码可以使用多少个输入字符。我对输入流的指定精度可能比类型可以表示num
的精度高得多的情况特别感兴趣。float
因此,在这种情况下,代码是否会读取所有代码(直到但不包括下一个非数字输入)或仅读取float
.
输入在 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。
因此,流将消耗所有有效的数字模式(即使在溢出之后),并且将相应地设置状态。
请参阅std::istream::operator>> docs中有关“(1) 算术类型”的信息。这使用num_get::get()
和文档的相关部分说明“只要一个字符不能成为有效数字表达式的一部分,该函数就会停止从序列中读取字符”。
因此,从文档看来,所有可用的数字都将被读取,但如果浮点类型太“窄”,则不会全部使用它们。
您可以通过一个小实验来测试其中的一部分:
#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
并使用您知道的位数多于 a 的输入运行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;
。