All is in the title. How to check a possible overflow when using the two functions exp() and log()?
5 Answers
#include <errno.h>
When an oferflow occurs, then errno is set to ERANGE.
Next time, do your homework before asking.
Googling: "c++ exp" returned this as the first result http://www.cplusplus.com/reference/cmath/exp/
In the middle of the page, there is EXACTLY what you're looking for.
 
    
    - 1,506
- 1
- 8
- 17
- 
                    The aim is to check for overflow before it occurs. Otherwise, un undefined behavior will be generated. – WildThing Jul 11 '13 at 10:24
- 
                    2It's easier than you think. Just try and if errno is set to ERANGE try again with different values. This approach is *simple*, *cheap* and yet *effective*. – gifnoc-gkp Jul 11 '13 at 10:25
- 
                    This is a post-test for the overflow that is not applicable for my problem since the inputs vary each time. i want to check the possible overflow before it occurs – WildThing Jul 11 '13 at 10:37
- 
                    @user2114690 In which case, call the function, throw out the results, and check for `ERANGE`. If it's not set, you can then call the function and use the results. – James Kanze Jul 11 '13 at 10:40
- 
                    3@user2114690 I think I understand your worry. But overflow in one of the functions in `` is _not_ undefined behavior, so you don't have to worry about avoiding it up front; checking after is safe and sufficient. – James Kanze Jul 11 '13 at 10:42
- 
                    1Good answer I was unaware of `ERANGE`, you could also include for c99, c+11 - `FE_OVERFLOW ` and `ERANGE` , additionally one should avoid *"Next time, do your homework before asking."* and about google, kind of statements in answer, you may comment. (just my suggestion) Anyways good finding Thanks for your answer! – Grijesh Chauhan Jul 11 '13 at 13:22
- 
                    errno is only set by math library functions if `(math_errhandling & MATH_ERRNO)` is non-zero. The standard does not require that errno be set, otherwise. – Stephen Canon Jul 11 '13 at 14:06
To expand the answer of @TheOtherGuy, you can cancel the operation if overflow occurs.
#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;
}
 
    
    - 39,972
- 7
- 52
- 94
- 
                    1i think you are wrong, To create a conforming program you need to test for overflow before generating said overflow. look at this http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c – WildThing Jul 11 '13 at 10:42
- 
                    1Added to what @James Kanze said, i think that i were wrong. your solution is correct. Thank you – WildThing Jul 11 '13 at 11:21
- 
                    3@user2114690 For a compilation platform that provides IEEE 754 floating-point arithmetic, it is not necessary to test the argument for overflow because when `exp(param)` is too large to be represented, it results in IEEE 754 value `+inf` and does not cause undefined behavior. Question 199333 is about integer overflow and does not apply to IEEE 754 floating-point implementations. – Pascal Cuoq Jul 11 '13 at 11:55
- 
                    2Note that, in general, you need to set `errno` to 0 before you call a function in order to get a meaningful result. This simple example works because `errno` is 0 on startup, but **any** library function is allowed to set `errno`, so seeing `ERANGE` after calling `exp` does **not** mean that `exp` set it unless you set `errno` to 0 before calling `exp`. – Pete Becker Jul 11 '13 at 11:57
- 
                    1@PascalCuoq Does errno capture the OVERFLOW generated by exp(param)--> inf? – WildThing Jul 11 '13 at 12:12
- 
                    1errno is only set by math library functions if (math_errhandling & MATH_ERRNO) is non-zero. The standard does not require that errno be set, otherwise. – Stephen Canon Jul 11 '13 at 14:07
The best way to check for overflow beforehand is to do so intelligently on a case-by-case basis.
Using your knowledge of logarithms and exponents, you should be able to identify potential overflows using properties like INT_MAX: examine these C++ Limitations
I threw a rough sample c++ execution together, assuming you know beforehand what limits you are attempting to follow.
#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;
}
If you're looking to catch the errors post mortem, examine errno in range.
 
    
    - 1,797
- 3
- 21
- 36
For the exp() handling:
Just compare against a variable which you assign to log(FLT_MAX). FLT_MAX is biggest float. You can do this before calculating an exp(). Because log() is inverse of 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;
}
For the log() handling:
1)You cannot everflow log(x) before overflowing x. (for the upper bound)
2)Float's/Double's (x) precision is not enough to overflow to negative-infinity for log(x).
3)Make sure x is bigger than zero.
 
    
    - 11,469
- 4
- 45
- 97
- 
                    1Where did you get your biggest float from? It is platform dependent, and there are means of obtaining it for any platform. – juanchopanza Jul 11 '13 at 10:45
- 
                    Then he should het his platform's limit before checking against an overflow before calculation. – huseyin tugrul buyukisik Jul 11 '13 at 10:48
- 
                    You should suggest that in your answer instead of quoting some weird number and claiming it is the biggest float :) – juanchopanza Jul 11 '13 at 10:49
Better than prevent, you can catch the exception:
try {
    z=exp(n);
} catch (...) {
    puts("Can't calcute exp...");
}
 
    
    - 10,823
- 1
- 23
- 46
- 
                    
- 
                    2`exp` does **not** throw an exception on overflow. There is a **floating-point exception**, but that's a different meaning of "exception" specific to floating-point. It has nothing to do with C++ exceptions – Pete Becker Jul 11 '13 at 11:54
 
    