gpt4 book ai didi

c++ - 在 libc++ 和 glibc 中解析 double 时不一致的字符串流行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:28 25 4
gpt4 key购买 nike

使用 gcc 编译以下示例时和 clang ...

#include <sstream>
#include <iostream>

int main() {
double val;
std::stringstream ss("6.93758e-310");
ss >> val;

std::cout << "fail: " << ss.fail() << std::endl
}

...我有不同的行为:

  1. 对于 gcc,流的失败位 ss.fail() 未设置,而
  2. 为 clang 设置

可能需要注意的是,在这两种情况下,errno 都设置为 ERANGE

此外,我在本地使用 clang 和 gcc 时会得到相同的行为,除非我明确使用 libc++ 和 clang (-stdlib=libc++) 而不是 glibc。

我不确定正确的行为是什么,但我觉得它应该是一致的。

最佳答案

输入流提取操作符的行为指定如下:

[istream.formatted.arithmetic] As in the case of the inserters, these extractors depend on the locale’s num_get<> ([locale.num.get]) object to perform parsing the input stream data. These extractors behave as formatted input functions (as described in [istream.formatted.reqmts]). After a sentry object is constructed, the conversion occurs as if performed by the following code fragment:

using numget = num_get<charT, istreambuf_iterator<charT, traits>>;
iostate err = iostate::goodbit;
use_facet<numget>(loc).get(*this, 0, *this, err, val);
setstate(err);

In the above fragment, loc stands for the private member of the basic_ios class.

[facet.num.get.virtuals] 有点冗长,但相关部分是:

For a double value, the function strtod.

... if the field represents a value outside the range of representable values, ios_base::failbit is assigned to err.

strtod在C++标准中没有规定,但在C标准中。相关位:

7.20.1.3 The strtod, strtof, and strtold functions

§10 If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE is implementation-defined.

引用规则:

7.12.1 Treatment of error conditions

§5 The result underflows if the magnitude of the mathematical result is so small that the mathematical result cannot be represented, without extraordinary roundoff error, in an object of the specified type.204) If the result underflows, the function returns an implementation-defined value whose magnitude is no greater than the smallest normalized positive number in the specified type; if the integer expression math_errhandling & MATH_ERRNO is nonzero, whether errno acquires the value ERANGE is implementation-defined; if the integer expression math_errhandling & MATH_ERREXCEPT is nonzero, whether the ‘‘underflow’’ floating-point exception is raised is implementation-defined

204)The term underflow here is intended to encompass both ‘‘gradual underflow’’as in IEC 60559 and also ‘‘flush-to-zero’’underflow.


虽然 C++ 没有指定浮点运算的表示方式,但您的系统可能使用 IEEE-754 (IEC 60559)。

IEEE-754 规定下溢为:

7.5.0 (simplified)

The underflow exception shall be signaled when a tiny non-zero result is detected. This shall be when a non-zero result computed as though both the exponent range and the precision were unbounded would lie strictly between ±bemin.

其中 ±bemin 是最接近零的正值或负值正常。它还说:

The implementer shall choose how tininess is detected


因此,回答您的陈述:

it feels to me like it should be consistent.

那会很好,但是围绕下溢的许多行为都指定为实现定义的。

坦率地说,输入流 API 是受限的,因为在检测到下溢的情况下,它不能保证访问舍入值,也不能提供区分下溢故障和其他故障的方法。

关于c++ - 在 libc++ 和 glibc 中解析 double 时不一致的字符串流行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54652243/

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