解析并转换denorm数字?

时间:2013-10-28 02:17:30

标签: c++ string c++11 floating-point floating-point-conversion

在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值?

4 个答案:

答案 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十进制数字。

例如,科学表示法中,具有往返精度的IEEE-754 64位双精度为"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方法不同,这也适用于十六进制浮点数。