8

一切尽在标题中。使用 exp() 和 log() 两个函数时如何检查可能的溢出?

4

5 回答 5

12
#include <errno.h>

当发生 anerflow 时,将errno设置为ERANGE


下一次,在问之前做你的功课。

谷歌搜索:“c++ exp”将其作为第一个结果返回http://www.cplusplus.com/reference/cmath/exp/
在页面中间,正是您要查找的内容。

于 2013-07-11T10:21:01.327 回答
7

要扩展@TheOtherGuy的答案,如果发生溢出,您可以取消操作。

#include <stdio.h>
#include <math.h>
#include <errno.h>

int main(void)
{
    double param, result;

    errno = 0;
    param = 1e3;
    result = exp (param);
    if (errno == ERANGE) {
        printf("exp(%f) overflows\n", param);
        result = param;
    }
    printf ("The exponential value of %f is %f.\n", param, result );
    return 0;
}
于 2013-07-11T10:33:17.040 回答
2

事先检查溢出的最佳方法是根据具体情况智能地进行检查。

使用您的对数和指数知识,您应该能够使用以下属性识别潜在的溢出INT_MAX:检查这些C++ 限制

假设您事先知道要遵循的限制,我将粗略的示例 c++ 执行放在一起。

#include <iostream>

// nTh root calculator
bool is_exp_overflow(int input_val, int exponent)
{
   my_max = pow(INT_MAX, (1/exponent);
   if (input_val > my_max)
   {
      return true;
   }
   else
      return false;
}

void runExp(int my_input, int my_exp)
{
   // Do maths
}

int main()
{
   int my_input = 0;
   int my_exp = 0;
   std::cout << "Enter test value\n";
   std::cin >> my_input;
   std::cout << "Enter test exponent\n";
   std::cin >> my_exp;
   bool exp_unsafe = 1;
   exp_unsafe = is_exp_overflow(my_input, my_exp);

   if (!exp_unsafe)
      runExp(my_input, my_exp);
   else
      std::cout << "Code is unsafe\n";

   return 0;
}

如果您希望在事后发现错误,请检查errno in range

于 2013-07-11T10:25:19.753 回答
2

对于 exp() 处理:

只需与您分配给 log(FLT_MAX) 的变量进行比较。FLT_MAX 是最大的浮点数。您可以在计算 exp()之前执行此操作。因为log()exp()的倒数。

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    float a=1E+37f; // an example of maximum finite representable floating-point number.
    //max value can change with platform so,
    //either use definitions or use a function you wrote
    // a= getMaxFloat(); or a=FLT_MAX
    float b=log(a); // limit of float to give in exp(); 
    float c=3242325445.0f; // test variable
    cout << "Hello world!" << endl;
    if(c>b){cout<<"you should not take exp of "<<c<<endl;}else{cout<<"go on"<<endl;}

    return 0;
}

对于 log() 处理:

1)在溢出x之前你不能永远流日志(x)。(对于上限)

2)浮点数/双精度(x)不足以溢出到log(x)的负无穷大。

3)确保x大于零。

于 2013-07-11T10:33:25.853 回答
1

比阻止更好,您可以捕获异常:

try {
    z=exp(n);
} catch (...) {
    puts("Can't calcute exp...");
}
于 2013-07-11T10:52:14.667 回答