IEEE754 etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
IEEE754 etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

14 Ocak 2020 Salı

IEEE754 - Float

1. Assignment
Assignment işleminde range ve precision artışı olmaz. Açıklaması şöyle.
Except for assignment and cast (which remove all extra range and precision), the values of operations with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.
Örnek
Elimizde şöyle bir kod olsun. Eğer x NaN değilse y == x her zaman true sonuç döner.
float x = ...

float y = x;

assert(y == x)
3. Integer'a Cast
Örnek
Anladığım kadarıyla undefined behavior vermeyen sadece iki tane yöntem var. Şöyle yaparız. reinterpret_cast, static_cast gibi yöntemler doğru değil
[[nodiscard]] constexpr float int_to_float4(int x) noexcept
{
  return std::bit_cast<float>(x);
}

[[nodiscard]] float int_to_float5(int x) noexcept
{
  float destination;
  memcpy(&destination, &x, sizeof(x));
  return destination;
}
3. Cast
Örnek
Elimizde şöyle bir kod olsun.
long l=9223372036854775807L;
float f=static_cast<float>(l);
Bu işlem sonucunda elimize geçen float değerin ne olacağı std::fesetround() metodu ile atanan "rounding mode" ile belirleniyor. IEEE754 5 tane "rounding mode" tanımlıyor. Bunlar şöyle.
Rounding-direction attributes to nearest
1. roundTiesToEven
2. roundTiesToAway

Directed rounding attributes
1. roundTowardPositive
2. roundTowardNegative
3. roundTowardZero

4. Karşılaştırma
double ve float karşılaştırması doğru sonuç vermeyebilir.

Örnek
Şöyle yaparız ve sonuç olarak "no" alırız.
#include<iostream.h>
using namespace std;
int main()
{
  float x=1.1;
  if(x==1.1)
    cout<<"yes";
  else
    cout<<"no";
  return 0;
}

26 Ağustos 2019 Pazartesi

IEEE754 ve Division By Zero

Giriş
Bu yazıda hem floation point için division by zero hem de integer için division by zero ele alınıyor.

Açıklaması şöyle.
C++ standard does not force the IEEE 754 standard, because that depends mostly on hardware architecture.
1. IEEE 754  Destekleniyorsa
Eğer IEEE 754 standardı destekleniyorsa açıklaması şöyle.
If the second operand is zero, the behavior is undefined, except that if floating-point division is taking place and the type supports IEEE floating-point arithmetic (see std::numeric_limits::is_iec559), then:
  • if one operand is NaN, the result is NaN
  • dividing a non-zero number by ±0.0 gives the correctly-signed infinity and FE_DIVBYZERO is raised
  • dividing 0.0 by 0.0 gives NaN and FE_INVALID is raised
- Madde 1 bölen veya bölünen NaN ise sonuç NaN'dır diyor.
- Madde 2 eğer bölen artı veya eksi 0 ise ve bölünen sıfırdan farklı bir rakam ise sonu artı veya eksi sonsuzdur diyor.
- Madde 3 hem bölen hem de bölünen 0 ise sonuç NaN'dır diyor.

Bu maddeleri toplarsak şu açıklama uygun olur. Yani ters bir durum varsa sonuç NaN veya +Infinity veya -Infinity çıkar.
Floating point division by zero is well defined by IEEE and gives infinity (either positive or negative according to the value of the numerator (or NaN for ±0) ).
Benzer bir açıklama şöyle.
If the hardware/compiler implement correctly the IEEE 754 standard, the division will provide the expected INF, -INF and NaN,
Örnek
Elimizde şöyle bir kod olsun.
float f = 42;
float g = f / 0.0f;
printf("%f\n", g);
Çıktı olarak şunu alırız.
inf
Hardware Exception
Açıklaması şöyle. Hardware exception ile C++ exception farklı şeylerdir.
"If the divisor is zero and the dividend is a finite nonzero number, then the division by zero exception shall be signaled. The default result shall be a correctly signed infinity" (IEE 754 paragraph 7.2) (the “exception”
here refers to the IEEE 754 FP exception, not C++ exception...
Hardware exception'ı test etmek için std::fetestexcept() metodu kullanılır. C kullanıyorsak fetestexcept() metodu kullanılır.

Hardware Exception'ı C++'a exception'a çevirme işi tamamen derleyiciye özel.
GCC için GNU feenableexcept yazısına bakınız.
MSVC için Visual Studio _set_se_translator yazısına bakınız.

Exception Tipleri
Açıklaması şöyle.
IEEE 754 defines five basic types of floating point exceptions: invalid operation, division by zero, overflow, underflow and inexact. The first three (invalid, division, and overflow) are sometimes collectively called common exceptions. These exceptions can seldom be ignored when they occur. ieee_handler(3m) gives an easy way to trap on common exceptions only. The other two exceptions (underflow and inexact) are seen more often--in fact, most floating point operations incur the inexact exception--and they can usually, though not always, be safely ignored.
Hardware Exception ve Trap Yani Signal
Açıklaması şöyle.
Often, programmers do not write programs with exceptions in mind, so when an exception is detected, the first question asked is: Where did the exception occur? One way to locate where an exception occurs is to test the exception flags at various points throughout a program, but to isolate an exception precisely by this approach can require many tests and carry a significant overhead.

An easier way to determine where an exception occurs is to enable its trap. When an exception whose trap is enabled occurs, the operating system notifies the program by sending a SIGFPE signal (see the signal(5) manual page). Thus, by enabling trapping for an exception, you can determine where the exception occurs either by running under a debugger and stopping on receipt of a SIGFPE signal or by establishing a SIGFPE handler that prints the address of the instruction where the exception occurred. Note that trapping must be enabled for an exception to generate a SIGFPE signal; when trapping is disabled and an exception occurs, the corresponding flag is set and execution continues with the default result specified in TABLE 4-1, but no signal is delivered.
Örnek
Şöyle yaparız. Burada IEEE 754 standardının desteklendiğini ve exception fırlatmanın kapalı olduğunu varsaydık. Sonuç olarak a +inf , b -inf, c NaN değerini alır
double a = 1.0 / 0; //Madde 2
double b = -1.0 / 0; //Madde 2
double c = 0.0 / 0; //Madde 3
std::cout << a << b << c;
2. IEEE 754  Desteklenmiyorsa
Eğer IEEE 754 desteklenmiyorsa sonuç undefined. Açıklaması şöyle
C++ Standard 5.6.4
... If the second operand of / or % is zero the behavior is undefined
Bir çok C++ kütüphanesi bu durumu ele alabilmek için ayarlanabilir bir çağrı veriyor. Açıklaması şöyle
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]
Örnek - C++
Bazı C++ derleyicileri uyarı üretebilir. Elimizde şöyle bir kod olsun.
double d = 15.50;
std::cout<<(d/0)<<std::endl;
Şu uyarıyı üretebilir.
warning: division by zero [-Wdiv-by-zero]
     std::cout<<(d/0)<<std::endl;
3. Integer İçin Divison By Zero
Açıklamsası şöyle.
The behaviour of integer division by zero is undefined by the C++ standard. It is not required to throw an exception. Floating point division by zero is also undefined but IEEE754 defines it.
Örnek
Elimizde şöyle bir kod olsun. Bu kod hiç bir hata vermeyebilir. Visual Studio'da ise Exit Code -1073741676 ile uygulama sonlanır.
int d = 0;
d /= d;


27 Ağustos 2018 Pazartesi

IEEE754 ve Division By Infinity

Giriş
Açıklaması şöyle.
Any finite number divided by infinity results in zero under IEEE 754 (and therefore the same in most typical C++ implementations).

If the sign of the of numerator and denominator differ, the result will be negative zero, which is equal to zero
Örnek
Şöyle yaparız.
1./std::numeric_limits<double>::infinity()