Giriş
IEEE - 754 bazı aralıklara ayrılmıştır. Bu aralıklardan bir tanesi de Denormal veya SubNormal Number aralığı. Bunlar arasında geçişleri test etmek gerekir. Açıklaması şöyle
Floating-point numbers have several distinct "ranges":- Standard/Normal arithmetic- Subnormal arithmetic- Infinite arithmetic- NaN arithmetic- Zero arithmetic
For instance, if I add any normal number to an infinite number, I need to get an infinite number back. If I add two large enough subnormals, I should get a normal number. Any math done on a NaN makes a NaN. Adding two large normals might get me an Inf.
Denormal Sayı Nedir?
Denormal sayılar (aynı zamanda denormalized number veya subnormal number olarak ta bilinir) 0 ile en küçük kayan nokta sayısı arasında kalan sayılardır. Denormal Number minimum exponent ile temsil edilir. Yani exponent 'in tüm bitleri 0'dır. Yani Denormal sayılar 0.xyz şeklinde temsil edilmeleri gerekiyor
Denormal Sayı İle İşlem Yavaştır?
Why does changing 0.1f to 0 slow down performance by 10x? sorusuna verilen cevapta denormal sayılarla işlemin yavaş olduğu belirtiliyor. Buradaki soruda da bu sayılar ile işlemin daha yavaş olduğu anlatılmış.
Sayının Denormal Olduğunu Kontrol Etme
Örnek
Bir sayının denormal olduğu şöyle kontrol edilir.
public static bool IsDenormal(float f)
{
// when 0, the exponent will also be 0 and will break
// the rest of this algorithm, so we should check for
// this first
if (f == 0f)
{
return false;
}
// Get the bits
byte[] buffer = BitConverter.GetBytes(f);
int bits = BitConverter.ToInt32(buffer, 0);
// extract the exponent, 8 bits in the upper registers,
// above the 23 bit significand
int exponent = (bits >> 23) & 0xff;
// check and see if anything is there!
return exponent == 0;
}
İki Farklı Sayıya Çıkartma İşlemi
Denormal sayı desteği yüzünden A ve B birbirine çok yakın ama farklı iki sayı ise A - B hiç bir zaman 0 olmaz.
Denormalized Desteğini Kapatmak
Açıklaması şöyle
ÖrnekIn particular, the Java programming language requires support of IEEE 754 denormalized floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms. Floating-point operations do not "flush to zero" if the calculated result is a denormalized number.
Açıklaması şöyle.
If you disable IEEE conformance using a special denormals-are-zero (DAZ) or flush-to-zero (FTZ) mode of the CPU, then indeed you could subtract two small, close numbers which would otherwise result in a subnormal number, which would be treated as zero due to the mode of the CPU.
Desteği kapatan şöyle bir kod olsun.
MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); // system specific
double d = std::numeric_limits<double>::min(); // smallest normal
double n = std::nextafter(d, 10.0); // second smallest normal
double z = d - n; // a negative subnormal (flushed to zero)
std::cout << (z == 0) << '\n' << (d == n);
Çıktı olarak şunu alırız
1
0
Hiç yorum yok:
Yorum Gönder