2013-11-23 21 views
6

Tôi đang cố gắng để thực hiện eps(x) chức năng của Matlab trong C++Thực hiện eps Matlab (x) hàm trong C++

Ví dụ, trong Matlab:

>> eps(587.3888) 
ans = 1.1369e-13 
>> eps(single(587.3888)) 
ans = 6.1035e-05 

Tuy nhiên, khi tôi cố gắng để làm điều này trong C++ Tôi không thể có được câu trả lời chính xác duy nhất.

#include <limits> 
#include <iostream> 
#include <math.h> 

#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) 
#define DEBUG2(x) do { std::cerr << #x << ": " << x << std::endl; } while (0) 

int main() { 

    float epsf = std::numeric_limits<float>::epsilon(); 
    DEBUG2(epsf); 
    double epsd = std::numeric_limits<double>::epsilon(); 
    DEBUG2(epsd); 

    float espxf = nextafter(float(587.3888), epsf) - float(587.3888); 
    double espxd = nextafter(double(587.3888), epsd) - double(587.3888); 
    DEBUG2(espxf); 
    DEBUG2(espxd); 

} 

Chạy chương trình tôi nhận được kết quả như sau:

$ ./a.out 
epsf: 1.19209e-07 
epsd: 2.22045e-16 
espxf: -1.13687e-13 
espxd: -1.13687e-13 

Có vẻ như vì một lý do mặc dù các giá trị eps cho đơn và đôi chính xác là chính xác, sản lượng sử dụng nextafter chức năng chỉ ra giá trị chính xác kép. Giá trị của tôi cho epsxf phải là 6.1035e-05 vì nó nằm trong Matlab.

Mọi suy nghĩ?

+0

'eps' của MATLAB luôn mang lại kết quả tích cực. Đoạn mã trên sẽ cho kết quả âm nếu 'x' lớn hơn' epsf'. [Ở đây] (http://coliru.stacked-crooked.com/a/68546c8c401c0610) 's mã cố định: 'double eps (float x) {float xp = std :: abs (x); double x1 = std :: nextafter (xp, xp + 1.0f); return x1 - xp; } ' – legends2k

Trả lời

6

Bao gồm <cmath> và gọi std::nextafter và mã của bạn sẽ hoạt động, miễn là bạn có trình biên dịch C++ 11.

Bao gồm <math.h> và gọi ::nextafter gọi phiên bản C của hàm. Việc triển khai C của nextafter rõ ràng là không hỗ trợ quá tải, vì vậy C cung cấp một kết quả có độ chính xác đơn nextafterf, cũng như nextafterl cho độ chính xác gấp bốn lần. (Đơn giản chỉ cần gọi chính xác hai lần nextafter với float không thành công vì đối số được chuyển đổi thành double.) Nếu bạn không có trình biên dịch C++ 11, bạn có thể sửa mã của mình bằng cách gọi ::nextafterf.

+0

wow cảm ơn bạn rất nhiều! – kyle

1

Sử dụng thư viện. Chức năng eps của Matlab trong các ngôn ngữ khác được gọi là ULP, cho đơn vị ở vị trí cuối cùng. Theo bài viết trên Wikipedia về ULP, chức năng sau đây từ boost C++ library thể được sử dụng để tính toán khoảng cách điểm nổi giữa hai đôi ab:

boost::math::float_distance(a, b) 

Các tài liệu cho float_distancehere.

+0

có, cảm ơn bạn Tôi đã biết về việc thực hiện tăng cường, tuy nhiên đối với lớp học của chúng tôi, chúng tôi không thể sử dụng các thư viện tăng cường. – kyle

+0

Tôi thực sự tự hỏi làm thế nào trên thế giới câu trả lời này tỷ lệ bỏ phiếu xuống. Tôi không chỉ giải thích khái niệm về ULP, nhưng tôi đề xuất một giải pháp thay thế mạnh mẽ hoạt động cho cả độ chính xác đơn và đôi. OP đã không chỉ ra mong muốn của mình không sử dụng tăng. – horchler

Các vấn đề liên quan