Trước hết, xin lỗi cho tiêu đề xấu:/kết quả không mong muốn với chế độ làm tròn cụ thể
Tôi đang cố gắng sao chép kết quả của giấy tính toán giá trị riêng của ma trận đối xứng tridiagonal. Tôi đang xác định một số giá trị 'giới hạn trên và dưới' bằng cách làm tròn để cộng và trừ vô cùng, tương ứng.
Thay vì thay đổi chế độ làm tròn mỗi lần, tôi chỉ sử dụng 'thủ thuật': fl⁻ (y) = -fl⁺ (-y), trong đó fl⁻ (y) là giá trị của y khi sử dụng dấu trừ chế độ làm tròn vô hạn và fl⁺ (y) là giá trị của y khi sử dụng chế độ làm tròn cộng với vô cùng. Vì vậy, tôi có đoạn mã sau trong C:
fesetround(FE_UPWARD);
first = - (-d[i] + x);
second = (- ((e[i-1]*e[i-1])/a_inf));
a_inf = first + second;
first = d[i] - x;
second = - ((e[i-1]*e[i-1])/a_sup);
a_sup = first + second;
và nó hoạt động tốt ngoại trừ một ví dụ trong đó a_inf mang lại cho tôi những kết quả đúng, nhưng a_sup cho kết quả sai, mặc dù cả hai biến đầu tiên và thứ hai dường như có cùng giá trị.
Tuy nhiên, nếu tôi làm như thế này:
fesetround(FE_UPWARD);
first = - (-d[i] + x);
second = (- ((e[i-1]*e[i-1])/a_inf));
fesetround(FE_DOWNWARD);
first = - (-d[i] + x);
second = (- ((e[i-1]*e[i-1])/a_sup));
tôi nhận được kết quả ngay. Vì vậy, nếu tôi sử dụng các trick fl⁻ (y) = -fl⁺ (-y), tôi nhận được kết quả đúng, nếu tôi thay đổi chế độ làm tròn và sử dụng biểu thức ban đầu tôi nhận được kết quả sai. Bất kỳ ý tưởng tại sao?
Trong cả hai trường hợp, các biến đầu tiên và giá trị thứ hai như sau:
first 1.031250000000000e+07, second -1.031250000000000e+07
first 1.031250000000000e+07, second -1.031250000000000e+07
Và các giá trị chính xác cho a_inf và a_sup là -1.862645149230957e-09 và + 1.862645149230957e-09, tương ứng, nhưng trong trường hợp a_sup đầu tiên = 0, đó là sai
gì tôi đoán nó đang xảy ra là một số loại hủy thảm khốc, nhưng tôi không có ý tưởng về làm thế nào để giải quyết nó trong trường hợp này ...
Cảm ơn nâng cao!
Ngôn ngữ này có thuyết bất khả tri không? – Lion
oops, quên rằng: /, tôi đã chỉnh sửa, đó là C. –
Vui lòng kiểm tra thời gian chạy để đặt chế độ làm tròn thành công. Tôi đã thấy nó trước đó 'fesetround' không có hiệu lực trên chế độ làm tròn. Một cái gì đó như 'test_rounding()' trong [ở đây] (http://reliablecomputing.eu/rigorousLP.c). Xin vui lòng tắt tối ưu hóa trình biên dịch hoàn toàn, nó được biết là mess up mọi thứ. – Ali