feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag, fetestexcept,
fegetenv, fegetround, feholdexcept, fesetround, fesetenv, feupdateenv,
feenableexcept, fedisableexcept, fegetexcept - zaokrąglanie
zmiennoprzecinkowe i obsługa wyjątków
Math library (
libm,
-lm)
#include <fenv.h>
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);
int fegetround(void);
int fesetround(int rounding_mode);
int fegetenv(fenv_t *envp);
int feholdexcept(fenv_t *envp);
int fesetenv(const fenv_t *envp);
int feupdateenv(const fenv_t *envp);
Tych jedenaście funkcji zdefiniowanych w C99 realizuje
obsługę zmiennoprzecinkowego zaokrąglania i
wyjątków (nadmiar, dzielenie przez zero, itp.).
Wyjątek
divide-by-zero (dzielenie przez zero) występuje,
gdy dokładnym wynikiem operacji na liczbach skończonych jest
nieskończoność.
Wyjątek
overflow (nadmiar) występuje, gdy wynik musi
być przedstawiony jako liczba zmiennoprzecinkowa, ale ma on
(dużo) większą wartość
bezwzględną niż największa (skończona)
liczba zmiennoprzecinkowa mająca przedstawienie.
Wyjątek
underflow (niedomiar) występuje, gdy wynik musi
być przedstawiony jako liczba zmiennoprzecinkowa, ale ma
mniejszą wartość bezwzględną niż
najmniejsza dodatnia znormalizowana liczba zmiennoprzecinkowa (i
nastąpiłaby duża utrata precyzji, gdyby
przedstawić go jako liczbę nieznormalizowaną).
Wyjątek
inexact (niedokładny) występuje, gdy wynik
operacji zaokrąglenia nie jest równy wynikowi o
nieskończonej precyzji. Może on towarzyszyć
wystąpieniu
overflow lub
underflow.
Wyjątek
invalid (nieprawidłowy) występuje, gdy
operacja nie ma dobrze zdefiniowanego wyniku, przykłady: 0/0,
nieskończoność - nieskończoność lub
sqrt(-1).
Wyjątki są reprezentowane na dwa sposoby: jako pojedyncze bity
(wyjątek obecny/nieobecny), które to bity odpowiadają w
pewien zależny od implementacji sposób pozycjom bitowym w
liczbie całkowitej, i jako nieprzezroczysta struktura, która
może zawierać więcej informacji o wyjątkach
(zapewne adres kodu, gdzie wyjątek wystąpił).
Każde z makr
FE_DIVBYZERO,
FE_INEXACT,
FE_INVALID,
FE_OVERFLOW,
FE_UNDERFLOW jest zdefiniowane, gdy implementacja
wspiera obsługę odpowiedniego wyjątku, i wówczas
definiuje odpowiedni(e) bit(y), umożliwiając wywoływanie
funkcji obsługi wyjątków, na przykład
podając argument całkowity
FE_OVERFLOW|
FE_UNDERFLOW. Dla innych wyjątków
może nie być wsparcia. Makro
FE_ALL_EXCEPT jest bitowym
OR wszystkich bitów odpowiadającym wspieranym wyjątkom.
Funkcja
feclearexcept() zeruje wspierane wyjątki reprezentowane
przez bity jej argumentu.
Funkcja
fegetexceptflag() umieszcza odwzorowanie stanu znaczników
przypisanych wyjątkom reprezentowanym przez argument
excepts w
nieprzezroczystym obiekcie
*flagp.
Funkcja
feraiseexcept() zgłasza wspierane wyjątki
reprezentowane przez bity
excepts.
Funkcja
fesetexceptflag() ustawia pełny stan o wartości
*flagp dla wyjątków reprezentowanych przez
excepts. Wartość ta musi być otrzymana jako wynik
wcześniejszego wywołania
fegetexceptflag() z ostatnim
argumentem zawierającym wszystkie bity
excepts.
Funkcja
fetestexcept() zwraca słowo z ustawionymi tymi bitami,
które są ustawione w argumencie
excepts i dla
których jest obecnie ustawiony odpowiedni wyjątek.
Tryb zaokrąglania określa w jaki sposób traktuje się
wynik operacji zmiennoprzecinkowej, jeśli nie może być on
dokładnie reprezentowany w mantysie. Mogą być dostarczane
różne tryby zaokrągleń: zaokrąglanie do
najbliższej liczby (domyślnie), zaokrąglanie w
górę (w kierunku dodatniej nieskończoności),
zaokrąglanie w dół (w kierunku ujemnej
nieskończoności) i zaokrąglanie w kierunku zera.
Każde z makr
FE_TONEAREST,
FE_UPWARD,
FE_DOWNWARD
oraz
FE_TOWARDZERO jest zdefiniowane, gdy implementacja wspiera
pobieranie i ustawianie odpowiedniego kierunku zaokrąglania.
Funkcja
fegetround() zwraca makro odpowiadające
bieżącemu trybowi zaokrąglania.
Funkcja
fesetround() ustawia tryb zaokrąglania podany jako jej
argument i zwraca zero, gdy się powiedzie.
C99 i POSIX.1-2008 określają identyfikator
FLT_ROUNDS
definiowany w
<float.h> wskazujący na zależny od
implementacji sposób zaokrąglania podczas dodawania
zmiennoprzecinkowego. Identyfikator ten może przyjmować
jedną z poniższych wartości:
- -1
- Nie można określić tryb
zaokrąglania.
- 0
- Zaokrąglanie w kierunku 0.
- 1
- Zaokrąglanie w kierunku najbliższej
liczby.
- 2
- Zaokrąglanie w kierunku dodatniej
nieskończoności.
- 3
- Zaokrąglanie w kierunku ujemnej
nieskończoności.
Inne wartości oznaczają tryby zaokrąglania niestandardowe,
zależne od architektury komputera.
Wartość
FLT_ROUNDS powinna odzwierciedlać
bieżący tryb zaokrąglania ustawiony przez
fesetround() (patrz także BŁĘDY IMPLEMENTACJI).
Całe środowisko zmiennoprzecinkowe, włączając
w to tryby sterowania i znaczniki stanu, może być
obsługiwane jako jeden nieprzezroczysty obiekt typu
fenv_t.
Środowisko domyślne jest określone przez
FE_DFL_ENV (typu
const fenv_t *). Są to ustawienia
środowiska przy uruchomieniu programu i są one zdefiniowane
przez ISO C jako: zaokrąglanie do najbliższej, wszystkie
wyjątki wyzerowane i tryb nieprzerywany (kontynuacja w przypadku
wystąpienia wyjątku).
Funkcja
fegetenv() zachowuje bieżące środowisko
zmiennoprzecinkowe w obiekcie
*envp.
Funkcja
feholdexcept() robi to samo, a następnie zeruje wszystkie
znaczniki wyjątków i ustawia tryb nieprzerywany (kontynuacja w
przypadku wystąpienia wyjątku), o ile to możliwe. Zwraca
zero, gdy się powiedzie.
Funkcja
fesetenv() odtwarza środowisko zmiennoprzecinkowe z
obiektu
*envp. Obiekt ten musi być znany jako poprawny, na
przykład jako wynik wywołania
fegetenv() lub
feholdexcept() lub jako równy
FE_DFL_ENV. To
wywołanie nie zgłasza wyjątków.
Funkcja
feupdateenv() instaluje środowisko zmiennoprzecinkowe
odwzorowane w obiekcie
*envp, poza tym, że obecnie
zgłoszone wyjątki nie są zerowane. Po jej
wywołaniu, zgłoszone wyjątki będą bitowym
OR tych zgłoszonych wcześniej oraz zawartych w
*envp. Jak
poprzednio, obiekt
*envp musi być znany jako poprawny.
Funkcje te zwracają zero, gdy się powiodą, lub
wartość niezerową, gdy wystąpi błąd.
These functions were added in glibc 2.1.
Informacje o pojęciach używanych w tym rozdziale można
znaleźć w podręczniku
attributes(7).
Interfejs |
Atrybut |
Wartość |
feclearexcept(), fegetexceptflag(),
feraiseexcept(), fesetexceptflag(), fetestexcept(),
fegetround(), fesetround(), fegetenv(),
feholdexcept(), fesetenv(), feupdateenv(),
feenableexcept(), fedisableexcept(),
fegetexcept() |
Bezpieczeństwo wątkowe |
MT-Safe |
IEC 60559 (IEC 559:1989), ANSI/IEEE 854, C99, POSIX.1-2001.
If possible, the GNU C Library defines a macro
FE_NOMASK_ENV which
represents an environment where every exception raised causes a trap to occur.
You can test for this macro using
#ifdef. It is defined only if
_GNU_SOURCE is defined. The C99 standard does not define a way to set
individual bits in the floating-point mask, for example, to trap on specific
flags. Since glibc 2.2, glibc supports the functions
feenableexcept()
and
fedisableexcept() to set individual floating-point traps, and
fegetexcept() to query the state.
#define _GNU_SOURCE /* Patrz feature_test_macros(7) */
#include <fenv.h>
int feenableexcept(int excepts);
int fedisableexcept(int excepts);
int fegetexcept(void);
Funkcje
feenableexcept() i
fedisableexcept()
włączają (wyłączają)
pułapkowanie poszczególnych wyjątków odwzorowanych
w przez
excepts i zwracają poprzednie ustawienie
pułapkowania wyjątków, jeśli się
powiodą, a -1 w pozostałych przypadkach. Funkcja
fegetexcept() zwraca bieżące ustawienie
pułapkowania wyjątków.
C99 określa, że wartość
FLT_ROUNDS powinna
odzwierciedlać zmiany bieżącego trybu zaokrąglania
ustawiane przez
fesetround(). Obecnie to nie działa:
FLT_ROUNDS ma zawsze wartość 1.
math_error(7)
Autorami polskiego tłumaczenia niniejszej strony podręcznika
są: Andrzej Krzysztofowicz <
[email protected]>, Robert
Luberda <
[email protected]> i Michał Kułach
<
[email protected]>
Niniejsze tłumaczenie jest wolną dokumentacją.
Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z
GNU
General Public License w wersji 3 lub nowszej. Nie przyjmuje się
ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy
zgłaszać na adres listy dyskusyjnej
[email protected]