Question

Consider

float num;
cin >> num;

Is it well defined how many characters of the input this code can consume. I am particularly interested in the case where the input stream may have the num specified in a much higher precision than what the float type can represent. So, in this case is it standardized whether the code would read all of it (up to but not including the next non-numeric input), or just up to the max precision of float.

Was it helpful?

Solution 2

See the info for "(1) arithmetic types" in the std::istream::operator>> docs. This uses num_get::get() and the relevant part of the docs for that states "The function stops reading characters from the sequence as soon as one character cannot be part of a valid numerical expression".

So from the documentation it seems that all available digits will be read, but they won't all be used if the float type is too "narrow".

OTHER TIPS

The input is defined in std::num_get 22.4.2.1.2:

Stage 3: The sequence of chars accumulated in stage 2 (the field) is converted to a numeric value by the rules of one of the functions declared in the header :

— For a signed integer value, the function strtoll.

— For an unsigned integer value, the function strtoull.

— For a floating-point value, the function strtold.

The numeric value to be stored can be one of:

— zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned to err.

— the most positive representable value, if the field represents a value too large positive to be represented in val. ios_base::failbit is assigned to err.

— the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.

Hence, the stream will consume all valid patterns of numbers (even after overflow) and the state will be set accordingly.

You can test parts of this with a little experiment:

#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;
}

Then compile:

$ g++ --version
g++ (GCC) 4.8.2
...

$ g++ -std=c++11 -pedantic -Wextra -Wall ./fltest.cpp

And run with input that you know has more digits than a float has:

$ echo '3.1415926535 foo' | ./a.out
3.14159
foo

So it seems that the extraneous extra precision is discarded (a single-precision floating-point number has a litte more than 7 decimal digits of precision.

You can play with the input and output precision to see what effects these have by putting, say:

std::cin.precision(7);

before the std::cin >> f; line or, say:

std::cout.precision(10);

before the std::cout << f; line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top