5 Ağustos 2019 Pazartesi

std::numeric_limits

Giriş
Şu satırı dahil ederiz.
#include <limits>
Eğer sabitleri macro olarak kullanmak istersek şu satırı dahil ederiz.
#include <climits>
digits Alanı
2'lik düzende kaç tane hane olduğunu belirtir. Yani aslında belirtilen tipin kaç bit olduğunu belirtir.

Örnek
Şöyle yaparız.
// returns 2^n
template <std::UnsignedIntegral T>
constexpr T power2(T n)
{
  assert(n < std::numeric_limits<T>::digits);
  return T(1) << n;
}
Örnek - double
Şöyle yaparız. Çıktı olarak 53 verir.
int bits = std::numeric_limits<double>::digits;
digits10 Alanı
Açıklaması şöyle. 10'luk düzende kaç tane hane olduğunu belirtir.
The value of std::numeric_limits<T>::digits10 is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow.
Örnek - float
C dilinde şöyle yaparız. Çıktı olarak 6 verir.
float     FLT_DIG /* 6 for IEEE float */

float 7 veya 8 haneye kadar sayı tutabilse bile - örneğin 16,777,216 - tüm 7 veya 8 haneli sayıları temsil edemediği için bu değer 6'dır.

epsilon Alanı
1 + eps > 1 denklemini sağlayan en küçük sayıdır. Toplama işleminde mantissa'nın son bitini etkiler. Epsilon yerine şu kullanım yanlıştır.
float result = 1.0f + std::numeric_limits<float>::min();
Değer olarak 2^-23 sayısıdır.  Bu da 1.1920929e-7 sayısına denk gelir.

is_iec559 metodu
Açıklaması şöyle. IEEE754 standardının desteklenip desteklenmediğini belirtir.
IEC 559, is identical with IEEE 754.
C veya C++ IEEE 754 desteğini şart koşmuyor.
The value representation of floating-point types is implementation-defined.
Örnek
Eğer IEEE754 standardının kullanılıp kullanılmadığını bulmak istiyorsak şöyle yaparız.
static_assert(std::numeric_limits<double>::is_iec559,
              "This code requires IEEE-754 doubles");
Örnek
Şöyle yaparız.
bool isFloatIeee754 = std::numeric_limits<float>::is_iec559();
Örnek
Şöyle yaparız.
static_assert(std::numeric_limits<double>::is_iec559, "Please use IEEE754");
is_specialized Alanı
std::numeric_limits her türlü tip ile kullanılabilir. Anlamsız olsa bilr şu kod derlenir.
class A {
public:
  int x;
public:
  A() : x(666) {}
};

A a = std::numeric_limits<A>::max();
A b = std::numeric_limits<A>::max();
std::numeric_limist'in belli tipler için özelleştirildiğini anlamak için bu alanı kullanıırız. Şöyle yaparız
template <typename T>
void f() {
  if constexpr (std::numeric_limits<T>::is_specialized) {
    // use of std::numeric_limits<T>::max(), min(), etc.
  }
  else {
    // implement the rquired functionality differently
  }
}
has_infinity Alanı
Örnek
Şöyle yaparız. False döner.
std::numeric_limits<int>::has_infinity
lowest Alanı
Açıklaması şöyle. En küçük eksi sayısı döner.
Returns the lowest finite value representable by the numeric type T, that is, a finite value x such that there is no other finite value y where y < x. This is different from std::numeric_limits<T>::min() for floating-point types.
C#'ta şöyle yaparız.
float.MinValue = -3.40282347E+38
min Alanı
Bu alan hep en küçük eksi sayıyı döndürürmüş gibi algılanıyor. Ancak aslında en küçük artı ve normalized float sayıyı döndürür.  min sayısından daha küçük denormalized sayılar olabilir. Açıklaması şöyle.
std::numeric_limits::min() is the smallest non-subnormal number.
Örnek - double
Şöyle yaparız.
double min = std::numeric_limits<double>::min();
Çıktı olarak şunu alırız.
min:  2.22507e-308
Örnek - float
FLT_MIN sayıdır. Açıklaması şöyle
minimum normalized positive floating-point number
Şöyle yaparız.
std::numeric_limits<float>::min() = 1.17549435e-038
Değer olarak 2^-126'dır. Çünkü exponent en az -126 olabilir. Bu da 1.1754944e-38 sayısına denk gelir. Biraz daha detaylı yazarsak  1.17549435e-38 sayısına denk gelir. Bellekte temsili ise şöyledir.
Exponent = 1
Mantissa = 0
Sign = 0
Exponent 1 -254 arasında olduğu için normalized sayı muamalesi görür.

Gerçek en küçük artı sayı ise 1.40129846e-45 sayısına denk gelir. Bellekte temsili ise şöyledir.
Exponent = 0
Mantissa = 1
Sign = 0
Exponent 0 olduğu için denormalized sayı muamelesi görür. Mantissa'yı 0 yapamayız çünkü o zaman sayı tamamen 0 olur. Bu yüzden 1 değeri veririz.

max Alanı
Örnek - float
En büyük pozitif float sayıyı döndürür. FLT_MAX sayısıdır. Açıklaması şöyle.
maximum representable finite floating-point number
Bellekte temsili ise şöyledir.
Exponent = 245
Mantissa = 0x7FFFF
Sign = 0
Bu da 3.40282347e+38 sayısına denk gelir.
Şöyle yaparız.
std::cout << "float\t"
          << std::numeric_limits<float>::lowest() << '\t'
          << std::numeric_limits<float>::min() << '\t'
          << std::numeric_limits<float>::max() << '\n';
quiet_NaN Alanı metodu
Örnek
Şöyle yaparız.
double slope = std::numeric_limits<double>::quiet_NaN();
std::cout << "slope is " << slope << std::endl;
Çıktı olarak şunu alırız.
slope is nan

Hiç yorum yok:

Yorum Gönder