【问题标题】:Catching overflow during exponentation of int or long long int在 int 或 long long int 求幂期间捕获溢出
【发布时间】:2023-04-08 23:57:02
【问题描述】:

在使用带有 int 或 long long int 的 pow() 函数时,有什么方法可以捕获溢出。

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
  int a = 2;//or long long int a = 2
  int b = 50;//or long long int b = 50
  if(!exponentation_overflows(a,b))//some function to check if there is no overflow
  {
    cout<<pow(a,b)<<endl;
  }

}

【问题讨论】:

  • 你会如何想象浮点值溢出的样子?已经在精度失败时?或者不是在浮动表示的绝对最大值出现之前?
  • 我可以考虑使用内联汇编来捕捉它,但我宁愿等着看是否有标准的方法来做到这一点。
  • 您需要在en.cppreference.com/w/cpp/numeric/math/pow 中未指定的哪些错误处理?
  • AFAIK,标准没有定义返回整数类型的 pow 函数 - 因此您可以使用 std::isnan(answer) 检查返回值。不过,这可能取决于实现。在您的情况下, pow(a, b) 会将 a 提升为加倍并返回加倍。

标签: c++ overflow undefined-behavior


【解决方案1】:

我知道这不是您要问的,但您可以编写自己的 pow 函数来检查结果是否小于前一个。

【讨论】:

    【解决方案2】:

    由于 pow 返回一个 double,它的范围比 int 或 long long int 大得多,因此您可以:

    bool exponentiation_overflows(int a, int b) {
        return pow(a, b) > double(MAXINT); // or double(MAXLONGLONG)
    }
    

    【讨论】:

      【解决方案3】:

      [...] int 或 long long int。

      自 C++11 起,标准函数 std::pow整数 数字有特定的重载。

      在这种情况下,您的参数将转换为 double 的表示形式。


      有没有办法捕捉溢出[...]

      是的,标准函数已经提供了错误处理机制。

      如果溢出:

      如果由于溢出导致极点错误或范围错误,则返回±HUGE_VAL、±HUGE_VALF或±HUGE_VALL。

      所以你的代码应该是这样的:

      #include <cmath>
      
      void pow_wrapper(const int base, const int exp) {
        const double result = std::pow(base, exp);
        if (result == HUGE_VAL) {
          // overflow detected
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        相关资源
        最近更新 更多