解析和转换去规范数字
Parse and convert denorm numbers?
在C++中,我们可以毫无问题地将无规范数存储到变量中:
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 值?
我不确定我是否理解了这个问题,但使用这样的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
显然,您可以使用cstdlib
中的strtod
(或较旧的atof
)界面。我怀疑这是否是保证的或便携式的。
我不确定它是否会有所作为,但您实际上正在打印:
(std::numeric_limits<double>::max_digits10 + 1) = 18
十进制数字。
例如,具有往返精度的 IEEE-754 64 位双精度以科学记数法"1.16"
。也许这是引入了一些干扰转换的 ULP/舍入?
非正规和std::stod
的问题在于后者是根据std::strtod
定义的,这可能会在下溢上设置errno=ERANGE
(它是由实现定义的,它是否这样做,并且在glibc中它确实如此)。正如 gcc 开发人员提醒的那样,在这种情况下,std::stod
由抛出std::out_of_range
的标准定义。
因此,正确的解决方法是直接使用 std::strtod
,当它返回的值有限且非零时忽略ERANGE
,如下所示:
double stringToDouble(const char* str, std::size_t* pos=nullptr)
{
errno=0;
char* end;
const auto x=std::strtod(str, &end);
if(errno==ERANGE)
{
// Ignore it for denormals
if(x!=0 && x>-HUGE_VAL && x<HUGE_VAL)
return x;
throw std::out_of_range("strtod: ERANGE");
}
else if(errno)
throw std::invalid_argument("strtod failed");
if(pos)
*pos=end-str;
return x;
}
请注意,与另一个答案中建议std::istringstream
方法不同,这也适用于十六进制浮点数。
相关文章:
- 查找最接近的大于当前数字的数字的索引
- 找到 x^n 的所有组合,并检查它们的总和是否等于一个不包括相同数字的数字
- C++ 中 11 位数字的数字的乘积
- 编写一个程序,提示用户输入一个整数,然后输出数字的单个数字和数字的总和
- 无法在按下数字和数字键时处理Qt C++中的QKey事件
- 如何通过C 从数字列表中以3位数字生成数字
- 浮点值未显示准确数字的数字C
- 该程序如何反向打印数字的数字?
- 分开二进制数字的数字
- 接收数字和数字的算法并检查数字内部数字的次数
- C++ - 计算一系列数字的数字
- 无符号函数,用于返回使用任何数字的数字
- bignumber.h arduino如何解析大于10位数字的数字
- 字母数字到数字在 c 歧义中
- 如何在递归函数中更改数字的数字?C++
- (数字)和(-数字)的含义
- 正则表达式:仅限数字 + 字母数字 + 特殊字符
- 在 c++ 中查找最小数字 +ve 数字
- 将字符串解析为数字或数字和百分比符号
- 比较数字并查找具有相同数字的数字