2013-07-11 30 views

Trả lời

7

Để mở rộng câu trả lời của @TheOtherGuy, bạn có thể hủy hoạt động nếu xảy ra tình trạng tràn.

#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

tôi nghĩ rằng bạn là sai, Để tạo ra một chương trình phù hợp, bạn cần phải kiểm tra cho tràn trước khi tạo tràn nói. xem http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-cc – WildThing

+0

@ user2114690 liên kết tốt này, cảm ơn –

+1

Đã thêm vào những gì @James Kanze đã nói, tôi nghĩ rằng tôi đã sai. giải pháp của bạn là chính xác. Cảm ơn bạn – WildThing

12
#include <errno.h> 

Khi một oferflow xảy ra, sau đó errno được thiết lập để ERANGE.


Lần sau, làm bài tập ở nhà trước khi hỏi.

Googling: "C++ exp" trở lại này là kết quả đầu tiên http://www.cplusplus.com/reference/cmath/exp/
Vào giữa trang, có chính xác những gì bạn đang tìm kiếm.

+0

Mục đích là để kiểm tra tràn trước khi nó xảy ra. Nếu không, hành vi không xác định sẽ được tạo ra. – WildThing

+2

Nó dễ hơn bạn nghĩ. Chỉ cần thử và nếu errno được đặt thành ERANGE, hãy thử lại với các giá trị khác nhau. Cách tiếp cận này là * đơn giản *, * rẻ * và * hiệu quả *. –

+0

Đây là một bài kiểm tra cho tràn mà không áp dụng cho vấn đề của tôi vì các đầu vào thay đổi theo từng thời điểm. tôi muốn kiểm tra tràn có thể trước khi nó xảy ra – WildThing

1

Cách tốt nhất để kiểm tra tràn trước là làm như vậy một cách thông minh trên cơ sở từng trường hợp cụ thể.

Sử dụng kiến ​​thức của bạn của logarit và số mũ, bạn sẽ có thể để xác định tràn tiềm năng sử dụng tài sản như INT_MAX: kiểm tra những C++ Limitations

Tôi ném một mẫu thô C++ thi với nhau, giả sử bạn biết trước những gì giới hạn bạn đang cố gắng để làm theo.

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

Nếu bạn đang tìm kiếm để bắt các lỗi nghiệm tử thi, kiểm tra errno in range.

2

Đối với exp() xử lý:

Chỉ cần so sánh với một biến mà bạn gán cho log (FLT_MAX). FLT_MAX là phao lớn nhất. Bạn có thể làm điều này trước khi tính toán điểm kinh nghiệm(). Vì nhật ký() là nghịch đảo của điểm kinh nghiệm().

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

Đối log() xử lý:

1) Bạn không thể everflow log (x) trước khi tràn x. (đối với giới hạn trên)

2) Độ chính xác của Float/Đôi (x) không đủ để tràn đến mức âm vô cùng cho log (x).

3) Đảm bảo x lớn hơn 0.

+1

Bạn lấy phao lớn nhất từ ​​đâu? Đó là nền tảng phụ thuộc, và có phương tiện để có được nó cho bất kỳ nền tảng. – juanchopanza

+0

Sau đó, anh ta nên hạn chế giới hạn của nền tảng của mình trước khi kiểm tra chống tràn trước khi tính toán. –

+0

Bạn nên đề xuất rằng trong câu trả lời thay vì trích dẫn một số số lạ và tuyên bố đó là số float lớn nhất :) – juanchopanza

1

Tốt hơn Ngăn chặn, bạn có thể bắt các ngoại lệ:

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

... in C++. Trong c không có ngoại lệ. – urzeit

+2

'exp' không ** không ** ném một ngoại lệ trên tràn. Có một ** ngoại lệ dấu chấm động **, nhưng đó là một ý nghĩa khác của "ngoại lệ" cụ thể cho dấu phẩy động. Nó không liên quan gì đến ngoại lệ C++ –