为什么负 std::numeric_limits<float>::infinity() 在 Linux 上会触发流中的失败位,但在 AIX 上却不会

问题描述 投票:0回答:1

通过此测试,我在移植到 IBM Open XL C++ 17.1(clang 前端)时观察到不同的行为:

#include <iostream>
#include <limits>
#include <sstream>

#define FLT_INF (std::numeric_limits<float>::infinity())

int main() {
  std::stringbuf sb;
  float val = -FLT_INF;

  // write
  std::ostream ostr_(&sb);
  ostr_.setf(std::ios::scientific, std::ios::floatfield);
  ostr_.precision(17);
  ostr_ << val << "\n";

  // verify we can read from the hard-coded stream data
  float tmp = 0.f;

  std::istream istr_(&sb);
  istr_ >> tmp;
  std::cout << val << std::endl;
  std::cout << tmp << std::endl;
  std::cout << std::boolalpha << istr_.fail() << std::endl;

  return 0;
}

使用 Linux (GCC 11.4.1) 我看到以下行为(请注意,我在 Visual Studio 2022 中也看到了相同的行为):

-inf
0
true

但是在使用 IBM Open XL C++ 17.1 的 AIX 上我看到:

-INF
-INF
false

注意,在 AIX 上,已成功从流中读取无穷大值,并且未设置失败状态。

起初我认为这是 AIX 编译器的一个错误,但到目前为止我所做的少量阅读我不确定为什么所有其他平台都不能处理它。这似乎是一个合法的值

std::strtof
可以处理(至少根据我读过的内容,这就是
basic_istream::operator>>
所说的(通过幕后的
std::num_get
)。

我已经接近我对 C++ 的理解程度了。任何 C++ 专家都可以让我知道标准对行为明智的要求吗?两个编译器都对吗?

谢谢您的帮助。

c++ c++11
1个回答
0
投票

这个问题最终归结为这样一个事实:不同的编译器在 io 流的实现中以不同的方式对待无穷大。

请参阅LWG 2381(“解析浮点数的不一致”)了解更多信息(2014 年报告!)

如果您同时想要解决方法,

stof
似乎可以正常工作,但您必须先读取字符串。

© www.soinside.com 2019 - 2024. All rights reserved.