Przede wszystkim przepraszam za zły tytuł:/nieoczekiwane wyniki z specyficzny tryb zaokrąglania
Próbuję odtworzyć wyniki referat w sprawie obliczania wartości własnych o tridiagonal macierz symetryczna. Określam górne i dolne granice niektórych wartości poprzez zaokrąglenie do nieskończoności plus i minus.
Zamiast zmieniać za każdym razem tryb zaokrąglania, używam tylko "sztuczki": fl⁻ (y) = -fl⁺ (-y), gdzie fl⁻ (y) jest wartością y przy użyciu minus tryb zaokrąglania nieskończoności i fl⁺ (y) to wartość y, gdy używa się trybu zaokrąglania do plus nieskończoności. Tak, mam następujący fragment kodu w 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;
i to działa dobrze z wyjątkiem jednego przykładu, w którym a_inf daje mi prawo wynik, ale a_sup daje zły wynik, choć obu pierwszych i drugich zmiennych wydają się mieć te same wartości.
Jeśli jednak zrobić tak:
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));
uzyskać odpowiednie wyniki. Tak więc, jeśli użyję sztuczki fl⁻ (y) = -fl⁺ (-y), otrzymam właściwe wyniki, jeśli zmienię tryb zaokrąglania i użyję oryginalnego wyrażenia, otrzymam błędne wyniki. Każdy pomysł, dlaczego?
W obu przypadkach pierwsze i drugie zmienne wartości są następujące:
first 1.031250000000000e+07, second -1.031250000000000e+07
first 1.031250000000000e+07, second -1.031250000000000e+07
a poprawne wartości dla a_inf i a_sup są -1.862645149230957e-09 i + 1.862645149230957e-09, odpowiednio, ale w pierwszy przypadek a_sup = 0, co jest nie tak
Co Zgaduję, że dzieje się to jakiś katastrofalny odwołania, ale nie mam pojęcia, w jaki sposób go rozwiązać w tym przypadku ...
Dzięki z postęp!
Czy ten język jest niezobowiązujący? – Lion
oops, zapomniałem, że: /, edytowałem, to jest C. –
Proszę sprawdź, czy tryb zaokrąglania został pomyślnie ustawiony. Widziałem to wcześniej, że "fesetround" nie miał wpływu na tryb zaokrąglania. Coś jak 'test_rounding()' w [tutaj] (http://reliablecomputing.eu/rigorousLP.c). Proszę całkowicie wyłączyć optymalizację kompilatora, wiadomo, że zepsuje to. – Ali