在C ++中,我们可以将denorm数字存储到变量中而不会出现问题:
double x = std::numeric_limits<double>::denorm_min();
然后,我们可以毫无问题地打印这个变量:
std::cout<<std::setprecision(std::numeric_limits<double>::max_digits10)
std::cout<<std::scientific;
std::cout<<x;
std::cout<<std::endl;
它会打印出来:
4.94065645841246544e-324
但是当试图解析这个数字时会出现问题。想象一下,这个数字存储在一个文件中,并作为字符串读取。问题是:
std::string str = "4.94065645841246544e-324";
double x = std::stod(str);
会抛出std::out_of_range
个异常。
所以我的问题是:如何转换存储在字符串中的denorm值?
答案 0 :(得分:2)
我不确定我是否理解了这个问题,但使用std::istringstream
这样:
std::string str = "4.94065645841246544e-324";
double x;
std::istringstream iss(str);
iss >> x;
std::cout << std::setprecision(std::numeric_limits<double>::max_digits10);
std::cout << std::scientific;
std::cout << x << std::endl;
...给我:
4.94065645841246544e-324
答案 1 :(得分:0)
显然,您可以使用strtod
中的atof
(或较早的cstdlib
)界面。我怀疑这是保证还是便携。
答案 2 :(得分:0)
我不确定它是否会产生影响,但实际上是在打印:
(std::numeric_limits<double>::max_digits10 + 1) = 18
十进制数字。
"1.16"
。也许这会引入一些干扰转换的ULP /舍入?
答案 3 :(得分:0)
异常和mysql_connect
的问题在于后者是根据mysqli_connect
定义的,这可能会在下溢时设置std::stod
(由实现定义,是否会这样做,以及在glibc中)。正如by gcc developers所提醒的那样,在这种情况下,标准定义了std::strtod
以抛出errno=ERANGE
。
因此,正确的解决方法是直接使用std::stod
,当它返回的值是有限且非零时忽略std::out_of_range
,例如:
std::strtod
请注意,与another answer中建议的ERANGE
方法不同,这也适用于十六进制浮点数。