如何在使用常用数学函数exp()log()时防止溢出

How to prevent overflow when using usual math functions exp() log()?

本文关键字:log 溢出 exp 函数 常用数      更新时间:2023-10-16

所有内容都在标题中。当使用exp()和log()这两个函数时,如何检查可能的溢出?

#include <errno.h>

当发生错误流时,errno将设置为ERANGE


下次,在提问之前先做作业。

谷歌搜索:"c++exp"将其作为第一个结果返回http://www.cplusplus.com/reference/cmath/exp/
在页面的中间,有你正在寻找的东西。

要扩展@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) overflowsn", param);
        result = param;
    }
    printf ("The exponential value of %f is %f.n", param, result );
    return 0;
}

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

利用对数和指数的知识,您应该能够使用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 valuen";
   std::cin >> my_input;
   std::cout << "Enter test exponentn";
   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 unsafen";
   return 0;
}

如果您想在死后发现错误,请检查范围内的errno。

对于exp()处理:

只需与您分配给日志的变量(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之前对log(x)进行everflow。(对于上限)

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

3) 确保x大于零。

比预防更好,您可以捕获异常:

try {
    z=exp(n);
} catch (...) {
    puts("Can't calcute exp...");
}