gpt4 book ai didi

c++ - 为什么 std::istringstream 在不提升 failbit 标志的情况下生成错误的结果?

转载 作者:行者123 更新时间:2023-11-30 03:19:08 32 4
gpt4 key购买 nike

当我将包含 long doublestring 转换为 floatdouble 时,std: :istringstream 不会在 QNX 中引发 failbit 标志。

下面是演示代码:

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>

int main(){
const long double originaldNumber = std::numeric_limits<long double>::max() / 2;
float floatNumber;
std::string numberString = std::to_string(originaldNumber);

//From string to long double
std::istringstream iss(numberString);
iss >> floatNumber;

if (iss.fail())
std::cout<< "iss failed \n";

std::cout<< std::setprecision(30) << originaldNumber << "\n";
std::cout<< std::setprecision(30) << floatNumber << "\n";

return 0;
}

在 linux 中的输出是:

 iss failed 
5.94865747678615882510631926515e+4931
3.40282346638528859811704183485e+38

QNX 中的输出是:

5.94865747678615882510631e+4931
inf

QNX 版本:7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
工具链:gcc_ntox86_64

最佳答案

根据 cppreference.com,这是发生了什么:

std::istringstream::operator<<(float&) :

(5) extracts a floating point value by calling std::num_get::get()

std::num_get::get()

Stage 3: conversion and storage

The input is parsed as if by std::strtof

In any case, if the conversion function fails std::ios_base::failbit is assigned to err.

std::strtof

Return value

Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and HUGE_VAL, HUGE_VALF or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.

HUGE_VALF

HUGE_VALF Expands to positive float expression that indicates overflow


在你的例子中,很明显 std::strtof5.94...e+4931会溢出 float , 它应该返回 HUGE_VALF ,这是此函数的错误值。在 Linux 下:

float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << '\n'; // true
std::cout << "string repr: " << have_overflown << '\n'; // inf

Live demo

std::strtof有效返回 HUGE_VALF对于溢出的值,应该调用它的流的 failbit 被设置,正如 std::istringstream::operator<<(float&) 的规范中所规定的那样.

QNX 未满足此要求。您可以尝试检查它在链中的哪个位置出现故障。


根据 QNX doc on strtof :

If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.

你可以查看 errno反对ERANGE除了检查流故障位:

errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}

最后,如果您的实现未能像您在评论部分所说的 id 那样符合其自己的文档,您可以检查 floatNumber反对HUGE_VALF检测溢出。

关于c++ - 为什么 std::istringstream 在不提升 failbit 标志的情况下生成错误的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54005536/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com