📜  C++中的feupdateenv()函数(1)

📅  最后修改于: 2023-12-03 15:14:02.390000             🧑  作者: Mango

C++中的feupdateenv()函数

在C++中,feupdateenv()函数被用来设置浮点环境,即编译器用来执行浮点运算的设置。它的定义如下:

int feupdateenv(const fenv_t* envp);

其中,参数envp是指向保存当前浮点环境的fenv_t结构体的指针。如果envp指针为空,feupdateenv()函数将重置当前的浮点环境为默认设置。

该函数返回0表示成功设置了浮点环境,-1表示设置失败。

fenv_t

fenv_t结构体是一个C++标准库提供的浮点环境定义。它包含以下几个域:

  • unsigned short __control_word;
  • unsigned short __status_word;
  • unsigned short __tag_word;
  • unsigned short __unused1;
  • unsigned int __unused2;
  • unsigned int __unused3;
  • unsigned int __unused4;
  • unsigned int __unused5;

其中,__control_word代表控制分支;__status_word代表状态分支;__tag_word代表标记分支。

使用举例

以下是一个使用feupdateenv()函数的例子:

#include <iostream>
#include <cmath>
#include <cfenv>
#pragma STDC FENV_ACCESS ON

int main() {
  std::cout << "sin(pi/2) = " << std::sin(M_PI/2) << '\n';
 
  // 中断浮点异常结果等于 NaN
  std::fesetround(FE_TOWARDZERO);
  std::feclearexcept(FE_ALL_EXCEPT);
  std::cout << "sin(pi/2) = " << std::sin(M_PI/2) << '\n';
  if (std::fetestexcept(FE_INVALID)) {
    std::cout << "     FE_INVALID raised\n";
  }
 
  // 确认 errno 被清空了
  errno = 0;
 
  // 使用 feupdateenv() 恢复控制分支,恢复状态分支,同时不修改标记分支
  std::fenv_t env;
  std::feholdexcept(&env);            // 保存当前环境
  std::fesetround(FE_TOWARDZERO);
  std::feclearexcept(FE_ALL_EXCEPT);
  std::cout << "sin(pi/2) = " << std::sin(M_PI/2) << '\n';
  if (std::fetestexcept(FE_INVALID)) {
    std::cout << "     FE_INVALID raised\n";
  }
  std::feraiseexcept(FE_INVALID);     // 手动设置 invalid 单词
  if (errno == EDOM) {
    std::cout << "     errno == EDOM\n";
  } else {
    std::cout << "     errno == " << errno << '\n';
  }
  std::feupdateenv(&env);             // 恢复之前保存的环境
  if (std::fetestexcept(FE_INVALID)) {
    std::cout << "     FE_INVALID raised\n";
  }
}

此代码输出:

sin(pi/2) = 1
sin(pi/2) = -0
     FE_INVALID raised
sin(pi/2) = -0
     errno == EDOM
     FE_INVALID raised