Giriş
IEEE754 kayan nokta işlemlerinde exception atma yeteneği kapalı olarak başlar. Hataları yakalamak için bazı çağrılar ile bu yeteneği etkinleştirmek gerekiyor.
Exceptionlar Nelerdir
Bir sayının sıfıra bölünmesi (division by zero), taşma (overflow) gibi olaylar hardware trap'e sebep olur. Bu trap ise işletim sistemi tarafından yakalanır. Yakalanan trap'in software exception'a dönüştürülmesi gerekir.
1. Sıfıra Bölme (Division By Zero)
Bölünen sıfırdan farklı ve bölen sıfır ise IEEE754 sonucun artı veya eksi infinity çıkmasını söylüyor. Açıklaması şöyle.
Şöyle yaparız
IEEE754 ve Division By Zero yazısına taşıdım.
Örnek - C#
IEEE754 kayan nokta işlemlerinde exception atma yeteneği kapalı olarak başlar. Hataları yakalamak için bazı çağrılar ile bu yeteneği etkinleştirmek gerekiyor.
Exceptionlar Nelerdir
Bir sayının sıfıra bölünmesi (division by zero), taşma (overflow) gibi olaylar hardware trap'e sebep olur. Bu trap ise işletim sistemi tarafından yakalanır. Yakalanan trap'in software exception'a dönüştürülmesi gerekir.
1. Sıfıra Bölme (Division By Zero)
Bölünen sıfırdan farklı ve bölen sıfır ise IEEE754 sonucun artı veya eksi infinity çıkmasını söylüyor. Açıklaması şöyle.
Örnek
Invalid operation: mathematically undefined, e.g., the square root of a negative number. By default, returns qNaN. Division by zero: an operation on finite operands gives an exact infinite result, e.g., 1/0 or log(0). By default, returns ±infinity. Overflow: a result is too large to be represented correctly (i.e., its exponent with an unbounded exponent range would be larger than emax). By default, returns ±infinity for the round-to-nearest modes (and follows the rounding rules for the directed rounding modes). Underflow: a result is very small (outside the normal range) and is inexact. By default, returns a subnormal or zero (following the rounding rules). Inexact: the exact (i.e., unrounded) result is not representable exactly. By default, returns the correctly rounded result.
Şöyle yaparız
double a = 5.;
double b = 0.;
double c = a / b; //divide by zero
C++IEEE754 ve Division By Zero yazısına taşıdım.
Örnek - C#
C++ ile aynı şekilde çalışır. Bölen 0 ise sonuç +inf veya -inf çıkar. Şöyle yaparız.
Şöyle yaparız.
Şeklen şöyle
double total = 3.0;
int numberOf = 0;
var tot = total / numberOf; // tot is double, tot == double.PositiveInfinity
Örnek - JavaŞöyle yaparız.
double a = 1.0;
double b = 0.0;
double c = a / b;
boolean flag = Double.isNaN(c);
System.out.println(flag); // False?
System.out.println(c); // Infinity
2. Overflow Şeklen şöyle
Örnek
Şöyle yaparız.
Exceptionlarla ilgili metodlar fenv.h içinde tanımlı. Aslında exception kelimesini kullanıyorum ancak C dilinde gerçekte exception olmadığı için, hatalar bazı bitlerin kaldırılması şeklinde vurgulanıyor.
fetestexcept metodu
fetestexcept() ile kayan nokta işlemlerindeki hataları yakalamak mümkün.
feclearexcept() metodu
fetestexcept() ile hata bitlerini almadan önce feclearexcept() ile bitleri temizlemek gerekiyor. Örnek programı buradaki soruyu okurken gördüm.
C++11
C ile aynı şekilde kullanılıyor. Tek fark metodların std namespace içinde olması. Örneğin std::fetestexcept() gibi.
Windows
Visual Studio 2012'ye kadar C99 uyumlu olmadığı için başka metodları kullanmak lazım. Yukarıda anlatılan hardware trap'in software exception'a dönüşmesi için VS içinde bazı ayarlar yapmak gerekir.
Properties / Code Generation / Enable C++ Exceptions : Yes with SEH Exceptions seçeneğini etkinleştirmek gerekir. SEH (Structured Exception Handling) hem donanım hem de yazılım exceptionları için kullanılır.
_control87 metodu
Örnekte ilk _control87() çağrısı ile atanmış bitler alınıyor. Bazı bitler sıfırlanıyor ve ikinci _control87 çağrısı ile tekrar atanıyor.
_controlfp_s metodu yazısına taşıdım.
double a = DBL_MAX;C99
double b = 10.0;
double c = a * b; //Burada exception atılabilir.
Exceptionlarla ilgili metodlar fenv.h içinde tanımlı. Aslında exception kelimesini kullanıyorum ancak C dilinde gerçekte exception olmadığı için, hatalar bazı bitlerin kaldırılması şeklinde vurgulanıyor.
fetestexcept metodu
fetestexcept() ile kayan nokta işlemlerindeki hataları yakalamak mümkün.
feclearexcept() metodu
fetestexcept() ile hata bitlerini almadan önce feclearexcept() ile bitleri temizlemek gerekiyor. Örnek programı buradaki soruyu okurken gördüm.
C++11
C ile aynı şekilde kullanılıyor. Tek fark metodların std namespace içinde olması. Örneğin std::fetestexcept() gibi.
Windows
Visual Studio 2012'ye kadar C99 uyumlu olmadığı için başka metodları kullanmak lazım. Yukarıda anlatılan hardware trap'in software exception'a dönüşmesi için VS içinde bazı ayarlar yapmak gerekir.
Properties / Code Generation / Enable C++ Exceptions : Yes with SEH Exceptions seçeneğini etkinleştirmek gerekir. SEH (Structured Exception Handling) hem donanım hem de yazılım exceptionları için kullanılır.
_control87 metodu
Örnekte ilk _control87() çağrısı ile atanmış bitler alınıyor. Bazı bitler sıfırlanıyor ve ikinci _control87 çağrısı ile tekrar atanıyor.
void TurnOnFloatingExceptions()
{
unsigned int cw;
// Note : same result with controlfp
cw = _control87(0,0) & MCW_EM;
cw &= ~(_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW);
_control87(cw,MCW_EM);
}
_controlfp_s metodu_controlfp_s metodu yazısına taşıdım.
Hiç yorum yok:
Yorum Gönder