2009-07-20 30 views
5

Đang cố gắng chuyển mã java sang C++ Tôi đã vấp phải một số hành vi kỳ lạ. Tôi không thể nhận được thêm đôi để làm việc (mặc dù tùy chọn trình biên dịch/fp: nghiêm ngặt có nghĩa là "chính xác" nổi điểm toán học được thiết lập trong Visual Studio 2008).Tại sao tăng gấp đôi không chính xác trong một dự án Visual Studio 2008 cụ thể?

double a = 0.4; 
/* a: 0.40000000000000002, correct */ 

double b = 0.0 + 0.4; 
/* b: 0.40000000596046448, incorrect 
(0 + 0.4 is the same). It's not even close to correct. */ 

double c = 0; 
float f = 0.4f; 
c += f; 
/* c: 0.40000000596046448 too */ 

Trong một dự án thử nghiệm khác, tôi thiết lập nó hoạt động tốt (/ fp: hoạt động nghiêm ngặt theo IEEE754).

Sử dụng Visual Studio 2008 (tiêu chuẩn) với Không tối ưu hóa và FP: nghiêm ngặt.

Bất kỳ ý tưởng nào? Nó thực sự cắt ngắn để nổi? Dự án này thực sự cần hành vi tương tự trên cả hai mặt java và C++. Tôi có tất cả các giá trị bằng cách đọc từ cửa sổ gỡ lỗi trong VC++.

Giải pháp: _fpreset(); // Ý tưởng của Barry Kelly đã giải quyết nó. Một thư viện đã thiết lập độ chính xác FP xuống thấp.

+2

Bạn có thể đăng một chương trình thử nghiệm hoàn chỉnh nhỏ cùng với dòng lệnh chính xác được sử dụng để biên dịch (xem cửa sổ đầu ra, v.v.), minh họa vấn đề này không? Cách duy nhất tôi có thể tái tạo là bằng cách sử dụng 0.0f + 0.4f thay thế. –

+0

Chúng ta có thể giả định bạn nhận thức được sự thiếu chính xác của các loại dấu phẩy động không? Chính xác đến 7 chữ số thập phân thường được coi là ok vì độ chính xác in mặc định là 6. –

+0

@Evan, ví dụ của anh ta bị tắt bởi nhiều hơn sẽ được giải thích bởi sự không chính xác của dấu phẩy động. – Kevin

Trả lời

8

Điều duy nhất tôi có thể nghĩ là có lẽ bạn đang liên kết với một thư viện hoặc DLL đã sửa đổi độ chính xác của CPU thông qua từ điều khiển.

Bạn đã thử gọi _fpreset() từ float.h trước khi tính toán có vấn đề?

+0

Nó phải là một cái gì đó dọc theo những dòng, nhưng là 0,0 + 0,4 ngay cả một tính toán? Nó không thể được đánh giá tại thời gian biên dịch? Kiểm tra việc tháo gỡ có thể thiết lập xem chế độ float thời gian chạy có liên quan gì đến nó hay không, hoặc có điều gì đó không ổn trong thời gian biên dịch hay không. –

+0

Chắc chắn nó có thể được, nhưng nếu nó đã được đơn giản, nó sẽ được dễ dàng để tái sản xuất, không? –

+0

Tôi không biết, có thể một cái gì đó khác trong dự án là xác định/fp: ngu ngốc hoặc tương đương. Yêu thích cá nhân của tôi sẽ là một tập tin nguồn không phải là newline chấm dứt và do đó chương trình có hành vi không xác định, mặc dù tôi không giữ ra nhiều hy vọng bao giờ thấy rằng gây ra một lỗi trong tự nhiên ... –

3

Vâng, chắc chắn nó cắt ngắn để nổi. Tôi nhận được cùng một giá trị in ấn float f = 0.4 như bạn làm trong trường hợp "không chính xác". Hãy thử:

double b = 0.0 + (double) 0.4; 

Câu hỏi sau đó là lý do tại sao nó cắt ngắn để nổi. Không có lý do nào trong tiêu chuẩn để xử lý 0.0 + 0.4 như là một biểu thức chính xác đơn, vì các chữ số dấu phẩy động có độ chính xác gấp đôi trừ khi chúng có hậu tố để nói cách khác.

Vì vậy, điều gì đó phải can thiệp vào cài đặt của bạn, nhưng tôi không biết gì.

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