c++g++ieee-754

c++ std::stof() throws out_of_range for 5.87747175e-39


Consider the following code

#include <iostream>

int main()
{
  const std::string s("5.87747175e-39");
  float f = std::stof(s);
  std::cout << s << " - " << f << std::endl;
  return 0;
}

When compiled with g++ and executed, this throws std::out_of_range. However, as you can see here, 5.87747175e-39 is a valid float. How can this be?

In case it makes a difference, I am on amd64 Debian 12 which uses g++ version 12.2

For what it's worth, Python considers this a valid float

python3 -c 'print(float("5.87747175e-39"))'

Also, it appears that this problem extends to all denormalized floats. For example, "1.1754942e-38" is the largest valid IEEE-754 denormalized float, but stof() considers it an error. The smallest normalized float is "1.1754944e-38" which is what is reported as FLT_MIN


Solution

  • Looking at GCC's implementation of std::stof they throw this error if the float is smaller than FLT_MIN, not FLT_TRUE_MIN.

    The reason for this is probably because FLT_TRUE_MIN was introduced in C++17, while std::stof in C++11.