2013-07-11 13 views

risposta

7

Per espandere la risposta di @TheOtherGuy, è possibile annullare l'operazione in caso di overflow.

#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; 
} 
+1

penso che tu abbia torto, per creare un programma conforme devi testare l'overflow prima di generare detto overflow. guarda questo http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-cc – WildThing

+0

@ user2114690 buon link, grazie –

+1

Aggiunto a quanto detto da @James Kanze, penso che io era sbagliato. la tua soluzione è corretta Grazie – WildThing

12
#include <errno.h> 

Quando si verifica un oferflow, quindi errno è impostato ERANGE.


La prossima volta, fare il vostro lavoro prima di chiedere.

Googling: "C++ exp" ha prodotto questo come il primo risultato http://www.cplusplus.com/reference/cmath/exp/
Al centro della pagina, v'è esattamente quello che stai cercando.

+0

L'obiettivo è quello di verificare la presenza di troppo pieno prima che si verifichi. Altrimenti, verrà generato un comportamento non definito. – WildThing

+2

È più facile di quanto pensi. Prova e se errno è impostato su ERANGE prova ancora con valori diversi. Questo approccio è * semplice *, * economico * e tuttavia * efficace *. –

+0

Questo è un post test per l'overflow che non è applicabile al mio problema poiché gli ingressi variano ogni volta. Voglio controllare l'eventuale overflow prima che si verifichi – WildThing

1

Il modo migliore per controllare in anticipo l'overflow è farlo in modo intelligente, caso per caso.

Usando la vostra conoscenza dei logaritmi ed esponenti, si dovrebbe essere in grado di identificare potenziali overflow utilizzando le proprietà come INT_MAX: esaminare questi C++ Limitations

ho gettato un campione di massima C++ esecuzione insieme, a patto di sapere in anticipo quali limiti si sta tentando da seguire.

#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; 
} 

Se stai cercando di catturare gli errori post mortem, esaminare errno in range.

2

Per la movimentazione exp():

Basta confrontare con una variabile che si assegna il login (FLT_MAX). FLT_MAX è il più grande float. È possibile eseguire questa operazione prima del calcolando un exp(). Perché log() è inverso di 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; 
} 

Per la gestione di log():

1) Non è possibile Everflow log (x) prima traboccante x. (per il limite superiore)

2) La precisione di Float/Double (x) non è sufficiente per l'overflow per l'infinito negativo per log (x).

3) Assicurarsi che x sia maggiore di zero.

+1

Da dove hai preso il tuo galleggiante più grande? È dipendente dalla piattaforma e ci sono modi per ottenerlo per qualsiasi piattaforma. – juanchopanza

+0

Quindi dovrebbe controllare il limite della sua piattaforma prima di controllare un overflow prima del calcolo. –

+0

Dovresti suggerirlo nella tua risposta invece di citare un numero strano e affermare che è il più grande float :) – juanchopanza

1

Meglio prevenire, si può prendere l'eccezione:

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

... in C++. In c non ci sono eccezioni. – urzeit

+2

'exp' fa ** not ** genera un'eccezione su overflow. Esiste ** un'eccezione a virgola mobile **, ma si tratta di un diverso significato di "eccezione" specifica per virgola mobile. Non ha nulla a che fare con le eccezioni C++ –

Problemi correlati