Veri Türü Ölçüleri
Önceki Ek A. Kütüphanedeki C Dili Oluşumları Sonraki
Veri Türü Ölçüleri
Çoğu zaman, yazılımınızda her nesne için uygun bir C veri türü seçersiniz ve onun nasıl gösterildiği veya kaç bit kullandığıyla ilgilenmezsiniz. Böyle bir bilgiye ihtiyaç duyarsanız C dilinin kendisi bu bilgiyi sağlamaz. limits.h ve float.h başlık dosyaları size bu bilgiyi tüm ayrıntıları ile veren makrolar içerir.
Bir Tamsayı Veri Türünün Genişliğinin Hesaplanması
Çok bilinen sebeplerle bir yazılım bir tamsayı türünde kaç bit bulunduğunu bilmeye ihtiyaç duyabilir. Örneğin, long int türünde bir diziyi bir bit vektörü olarak kullanıyorsanız, bitlere n indisi ile aşağıdaki gibi erişebilirsiniz:
vector[n / LONGBITS] & (1 << (n % LONGBITS))
Burada LONGBITS, bir long int içindeki bitlerin sayısı olarak tanımlanmış olmalıdır.
C dilinde bir tamsayı veri türündeki bitlerin sayısını verecek bir işleç yoktur. Fakat onu, limits.h başlık dosyasında tanımlanmış olan CHAR_BIT makrosuyla hesaplayabilirsiniz.
CHAR_BIT
Bir char içindeki bitlerin sayısıdır. Birçok sistemde değeri sekizdir ve bu değer int türündendir.
tür ile belirtilecek herhangi bir veri türünün bitlerinin sayısını şöyle hesaplayabilirsiniz:
sizeof (tür) * CHAR_BIT
Bir Tamsayı Türün Aralığı
Varsayalım ki, sıfırdan bir milyona kadar bir aralıktaki tamsayı değerleri saklamak istiyorsunuz. Kullanabileceğiniz en küçük tür hangisidir? Bunun için genel bir kural yoktur; C derleyicisine ve hedef makineye bağlıdır. Hangi tür ile çalışacağınızı bulmak için limits.h başlık dosyasında tanımlanmış olan MIN ve MAX makrolarını kullanabilirsiniz.
Her işaretli tamsayı türü için tutabileceği en küçük ve en büyük değerleri veren bir çift makro vardır. Her işaretsiz tamsayı türü içinde böyle makrolar vardır; en büyük değer için, en küçük değer yani sıfır için.
Bu makroların değerlerinin hepsi tamsayı sabit ifadeleridir. char ve short int için MAX ve MIN makroları int türünden değerlere sahiptir. Diğer türlerin MAX ve MIN makrolarının değerleri de makro tarafından açıklanmış aynı türde değerlerdir. Örneğin, ULONG_MAX makrosunun değeri unsigned long int türündendir.
SCHAR_MIN
Bir signed char tarafından tutulabilen en küçük değerdir.
SCHAR_MAX
UCHAR_MAX
Sırasıyla signed char ve unsigned char tarafından tutulabilen en büyük değerlerdir.
CHAR_MIN
Bir char tarafından tutulabilen en küçük değerdir. char işaretli ise SCHAR_MIN'e eşittir, yoksa sıfırdır.
CHAR_MAX
Bir char tarafından tutulabilen en büyük değerdir. char işaretli ise SCHAR_MAX'a eşittir, yoksa UCHAR_MAX'a eşittir.
SHRT_MIN
Bir signed short int tarafından tutulabilen en küçük değerdir. GNU C kütüphanesinin çalıştığı çoğu makinede short tamsayılar 16 bit genişliktedir.
SHRT_MAX
USHRT_MAX
Sırasıyla signed short int ve unsigned short int tarafından tutulabilen en büyük değerlerdir.
INT_MIN
Bir signed int tarafından tutulabilen en küçük değerdir. GNU C kütüphanesinin çalıştığı çoğu makinede int tamsayılar 32 bit genişliktedir.
INT_MAX
UINT_MAX
Sırasıyla signed int ve unsigned int tarafından tutulabilen en büyük değerlerdir.
LONG_MIN
Bir signed long int tarafından tutulabilen en küçük değerdir. GNU C kütüphanesinin çalıştığı çoğu makinede long tamsayılar int ile aynı olarak 32 bit genişliktedir.
LONG_MAX
ULONG_MAX
Sırasıyla signed long int ve unsigned long int tarafından tutulabilen en büyük değerlerdir.
LONG_LONG_MIN
Bir signed long long int tarafından tutulabilen en küçük değerdir. GNU C kütüphanesinin çalıştığı çoğu makinede long long tamsayılar 64 bit genişliktedir.
LONG_LONG_MAX
ULONG_LONG_MAX
Sırasıyla signed long long int ve unsigned long long int tarafından tutulabilen en büyük değerlerdir.
WCHAR_MAX
Bir wchar_t tarafından tutulabilen en büyük değerdir. Bkz. Genişletilmiş Karakterlere Giriş.
limits.h başlık dosyası ayrıca işletim sistemi ve dosya sistemi sınırlarını belirleyen bazı sabitler de bulunmaktadır. Bu sabitler Sistem Yapılandırma Parametreleri bölümünde açıklanmıştır.
Gerçek Sayı Türü Makroları
Gerçek sayılara özel gösterim makineden makineye değişir. Çünkü gerçek sayılar dahili olarak yaklaşık niceliklerle gösterilir. Gerçek sayı verilerle çalışan algoritmalar çoğunlukla makinenin doğru gerçek sayı gösterim ayrıntılarına dikkat etmeyi gerektirir.
C kütüphanesindeki bazı işlevlerin kendileri bu bilgiye gereksinim duyar; örneğin, gerçek sayıları okumak ve basmak (Bkz. Akımlar Üzerinde Giriş/Çıkış) için ve trigonometrik ve gerçel işlevlerin (Bkz. Matematik) hesaplanmasında kullanılan algoritmalar yuvarlama hatalarından ve hassasiyet kayıplarından kaçınmak için bunu kullanır. Sayısal analiz teknikleri gerçekleştiren bazı kullanıcı yazılımları da çoğunlukla hata sınırlarının küçültmesi ya da hesaplanması sırasında bu bilgiye ihtiyaç duyar.
float.h başlık dosyası makinenizde kullanılan biçimi açıklar.
Gerçek Sayı Gösterimi ile İlgili Kavramlar
Bu bölümde gerçek sayı gösterimleri ile ilgili terminolojiye değinilmiştir.
Büyük ihtimalle gerçek sayılar için üstel gösterim veya bilimsel terimler olarak bu kavramların çoğuna zaten aşinasınızdır. Örneğin 123456.0 sayısı üstel olarak 1.23456e+05 biçiminde, 1.23456 sayısı ile 10 üssü 5'in çarpımı olarak gösterilir.
Daha biçimsel olarak, gerçek sayıların bit gösterimi aşağıdaki terimlerle karakterize edilebilir:
  • İşaret biti ya -1 ya da 1'dir.
  • Üs alma için taban, 1'den büyük bir tamsayıdır. Belirli bir gösterim için bu bir sabittir.
  • Üstel kısım tabanın kendisiyle kaç defa çarpılacağını gösterir. Bir belirli gösterim için üs değerinin alt ve üst sınırları birer sabittir.
    Kimi zaman gerçek sayının bit gösteriminde üssü ifade eden kısım bir sabit eklenmesiyle daima işaretsiz bir nicelik yapılır. Bu sadece bit alanlarını ayırıp gerçek sayıyı kendiniz oluşturmak isterseniz önemli olur, ancak GNU kütüphanesinde böyle bir işlem için destek yoktur.
  • Ondalık kısım her gerçek sayının bir parçası olan bir işaretsiz tamsayıdır.
  • Ondalık kısmın hassasiyeti. Eğer bit gösteriminde taban b ise hassasiyet, ondalık kısmın taban-b sayıda basamağıdır. Bu belirli bir gösterim için bir sabittir.
    Birçok gerçek sayı gösterimi ondalık kısım içinde bir örtük gizli bit içerir. Bu ondalık kısım içinde olduğu varsayılan bir bittir ancak bellekte saklanmaz, çünkü bir normalleştirilmiş sayı içinde daima 1 dir. Hassasiyet ile ilgili kısım kendi içinde çok sayıda gizli bit içerebilir.
    Tekrar belirtelim, GNU kütüphanesi gerçek sayıların düşük seviye (ikilik tabandaki bit gösterimi) gösterimleri ile ilgili oluşumlara destek sağlamamaktadır.
Bir gerçek sayının bit gösterimindeki ondalık kısım dolaylı olarak paydası üstel taban hassasiyetteki bir kesri ifade eder. Bu ondalık kısım ile gösterilebilecek en büyük sayı bu paydadan bir eksiği olduğundan kesrin değeri daima birden küçüktür. Bu bit gösteriminin matematiksel değeri bu kesir ile işaret ve üstel tabanın çarpımıdır.
Not
Ç.N. - Özgün metinde burada anlatılan biraz karışık olmuş. Kafa karıştırmamak için çevirmedim. Basitçe ifade etmek gerekirse 32 bitlik gerçek sayı gösterimiyle ifade edilebilecek en küçük değer 2-149 olsa da bu sayı float türü için 2-126 olarak normalleştirilmiştir. En azından GNU C kütüphanesinde bu böyle.
Gerçek Sayılar ile İlgili Makrolar
Bu makroların tanımlarını float.h başlık dosyasında bulabilirsiniz.
FLT_ ile başlayan makro isimleri float türü ile, DBL_ ile başlayanlar double türü ile ve LDBL_ ile başlayanlar da long double türü ile ilgilidir. (GCC hedef makinede bir veri türü olarak long double türünü desteklemezse, LDBL_ ile başlayan sabitler double türüne karşılık olan sabitlere eşitlenir.)
Bu makrolardan sadece FLT_RADIX bir sabit ifadesi olarak garantilidir. Burada listelenmiş diğer sabitler #if önişlemci komutu ya da durağan dizilerin boyutları gibi yerlerde sabit ifadesi olarak güvenilir olamaz.
ISO C standardı bu parametrelerin en küçük ve en büyük değerlerini belirtse de, GNU C gerçeklemesi hedef makinede desteklenen gerçek sayı gösterimlerini açıklayan değerleri kullanır. Yani GNU C prensip olarak ISO C gereksinimlerini hedef makinenin yapabildiği kadarıyla karşılar. Uygulamada tüm makinelerde bu destekler zaten vardır.
FLT_ROUNDS
Bu değer gerçek sayı toplamasında yuvarlama kipini belirler. Standart yuvarlama kiplerinin değerleri:
-1
Bu kip belirlenebilir değildir.
0
Sıfıra yuvarlar.
1
En yakın sayıya yuvarlar.
2
Pozitif sonsuza yuvarlar.
3
Negatif sonsuza yuvarlar.
Diğer değerler, eğer varsa, makine bağımlı standart dışı yuvarlama kiplerini belirtir.
Gerçek sayılar için IEEE standardı gereğince çoğu makinede 1 değeri kullanılır.
Aşağıdaki tabloda FLT_ROUNDS sabitinin olası değerleri ile yuvarlamanın nasıl yapıldığı gösterilmiştir. Yuvarlama IEEE tek hassasiyetli gerçek sayılar standardına uygun olarak yapılmıştır.
                0      1             2             3
 1.00000003    1.0    1.0           1.00000012    1.0
 1.00000007    1.0    1.00000012    1.00000012    1.0
-1.00000003   -1.0   -1.0          -1.0          -1.00000012
-1.00000007   -1.0   -1.00000012   -1.0          -1.00000012
FLT_RADIX
Bit gösteriminde üstel kısmın tabanına karşılık gelen değerdir. Bu bölümde açıklanan diğer makroların aksine bir sabit ifadesi olarak garantilidir. IBM 360 ve türevleri dışında bilinen tüm makineler için değeri 2 dir.
FLT_MANT_DIG
float veri türü için gerçek sayının ondalık kısmındaki taban-FLT_RADIX basamağın basamak sayısıdır. Aşağıdaki ifade ondalık kısım basamaklarının sınırlı olmasından dolayı 1.0'a gider (matematiksel olarak olmasada):
float radix = FLT_RADIX;

1.0f + 1.0f / radix / radix / … / radix
Burada radix, FLT_MANT_DIG kere uygulanır.
DBL_MANT_DIG
LDBL_MANT_DIG
Sırasıyla double ve long double veri türleri için gerçek sayının ondalık kısmındaki taban-FLT_RADIX basamağın basamak sayısıdır.
FLT_DIG
float türü için hassasiyeti belirleyen ondalık basamakların sayısıdır. Teknik olarak h ve i sırasıyla ikilik gösterimdeki hassasiyet ve taban ise ve ondalık basamakların sayısı o onluk gösterimdeki hassasiyet ise, örneğin, 10 tabanındaki o basamaklı bir gerçek sayı b tabanındaki h basamağa yuvarlanır ve o ondalık basamak sayısı değiştirilmeksizin tekrar geri alınır.
Bu makronun değerinin ISO C gereksinimlerini karşılamak üzere en azından 6 olacağı varsayılır.
DBL_DIG
LDBL_DIG
FLT_DIG'e benzerler ancak sırasıyla double ve long double veri türleri içindir. Bu makroların değerlerinin en azından 10 olacağı varsayılır.
FLT_MIN_EXP
float türü için ikilik gösterimdeki mümkün en küçük üs değeridir. Daha ayrıntılı ifade etmek gerekirse, float türündeki normalleştirilmiş bir gerçek sayı olarak FLT_RADIX değerinin bu değerden bir eksiğinin artan kuvvetlerinden elde edilebilecek en küçük değerini sağlayacak olan en küçük negatif tamsayıdır. (Pratikte float türü için en küçük değer 2-125-1 dir ve burada FLT_MIN_EXP -125 tir.)
DBL_MIN_EXP
LDBL_MIN_EXP
FLT_MIN_EXP'e benzerler ancak sırasıyla double ve long double veri türleri içindir.
FLT_MIN_10_EXP
float türü için onluk tabanda üssün en küçük negatif değeri olan bir tamsayıdır. Normalleştirilmiş gerçek sayıların mümkün en küçük değeri için 10'un bu değerden 1 eksiği artan kuvvetindeki değerine karşılıktır. Bu değerin -37 veya daha az olduğu varsayılır.
DBL_MIN_10_EXP
LDBL_MIN_10_EXP
FLT_MIN_10_EXP'e benzerler ancak sırasıyla double ve long double veri türleri içindir.
FLT_MAX_EXP
float türü için ikilik gösterimdeki mümkün en büyük üs değeridir. Daha ayrıntılı ifade etmek gerekirse, float türündeki normalleştirilmiş bir gerçek sayı olarak FLT_RADIX değerinin bu değerden bir eksiğinin artan kuvvetlerinden elde edilebilecek en büyük değerini sağlayacak olan en büyük pozitif tamsayıdır.
DBL_MAX_EXP
LDBL_MAX_EXP
FLT_MAX_EXP'e benzerler ancak sırasıyla double ve long double veri türleri içindir.
FLT_MAX_10_EXP
float türü için onluk tabanda üssün en büyük değeri olan bir pozitif tamsayıdır. Normalleştirilmiş gerçek sayıların mümkün en küçük değeri için 10'un bu değerden 1 eksiği artan kuvvetindeki değerine karşılıktır. Bu değerin en azından 37 olduğu varsayılır.
DBL_MAX_10_EXP
LDBL_MAX_10_EXP
FLT_MAX_10_EXP'e benzerler ancak sırasıyla double ve long double veri türleri içindir.
FLT_MAX
Bu makronun değeri float türünde ifade edilebilecek en büyük gerçek sayının değeridir. Bu değerin en azından 1E+37 olacağı varsayılır ve bu değer float türündendir.
İfade edilebilir en küçük sayı ise - FLT_MAX'tır.
DBL_MAX
LDBL_MAX
FLT_MAX'e benzerler ancak sırasıyla double ve long double veri türleri içindir. Makro değerinin veri türü kendi türü ile aynıdır.
FLT_MIN
Bu makronun değeri float türünde ifade edilebilecek en küçük gerçek sayının değeridir. Bu değerin 1E-37'den daha büyük olmayacağı varsayılır ve bu değer float türündendir.
DBL_MIN
LDBL_MIN
FLT_MIN'e benzerler ancak sırasıyla double ve long double veri türleri içindir. Makro değerinin veri türü kendi türü ile aynıdır.
FLT_EPSILON
1.0 + FLT_EPSILON != 1.0 gibi bir ifadeyi doğrulayan float türündeki en küçük pozitif gerçek sayıdır. 1E-5'den büyük olmayacağı varsayılır.
DBL_EPSILON
LDBL_EPSILON
FLT_MIN'e benzerler ancak sırasıyla double ve long double veri türleri içindir. Makro değerinin veri türü kendi türü ile aynıdır. Bu değerlerin 1E-9'dan daha büyük olmayacağı varsayılır.
IEEE Gerçek Sayı Gösterimleri
Burada, en genel gerçek sayı gösterimi olan [IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE Std 754-1985)] tarafından belirtilmiş gerçek sayı metrikleri için bir örnek gösterilmektedir. 1980 lerden sonra tasarlanan tüm bilgisayarlar bu biçimi kullanır.
IEEE tek hassasiyetli gerçek sayı biçimi ikilik tabanı kullanır. Bir işaret biti, 23 artı bir gizli bit olmak üzere (yani toplam hassasiyet 24 taban-2 basamak) 24 bitlik ondalık kısım ile -125 ile 128 aralığındaki üs değerleri için 8 bitlik üstel kısımdan oluşan bir gösterim sunar.
Bu gösterimin float veri türünü gerçeklemekte kullanılan ilgili değerleri aşağıda gösterilmiştir.
FLT_RADIX                             2
FLT_MANT_DIG                         24
FLT_DIG                               6
FLT_MIN_EXP                        -125
FLT_MIN_10_EXP                      -37
FLT_MAX_EXP                         128
FLT_MAX_10_EXP                      +38
FLT_MIN                 1.17549435E-38F
FLT_MAX                 3.40282347E+38F
FLT_EPSILON             1.19209290E-07F
Bunlar da double veri türü içindir:
DBL_MANT_DIG                         53
DBL_DIG                              15
DBL_MIN_EXP                       -1021
DBL_MIN_10_EXP                     -307
DBL_MAX_EXP                        1024
DBL_MAX_10_EXP                      308
DBL_MAX         1.7976931348623157E+308
DBL_MIN         2.2250738585072014E-308
DBL_EPSILON     2.2204460492503131E-016
Yapı Alanı Konum Ölçüleri
Bir yapı içindeki bir yapı üyesinin konumunu offsetof kullanarak bulabilirsiniz.
size_t offsetof
(tür, üye)
makro
İşlev, tür türündeki yapının üye isimli üyesinin konumunu bir tamsayı sabit olarak döndürür. Örneğin offsetof (struct s, elem) ifadesi, struct s içindeki elem üyesinin bayt cinsinden başlangıç konumunu verir.
Bu makro, üye bir bit alanı ise çalışmayacaktır. Bu durumda C derleyicisinden bir hata alırsınız.
Önceki Üst Ana Başlık Sonraki
Önemli Veri Türleri Başlangıç Ek B. Kütüphane Oluşumlarının Özeti
Bir Linux Kitaplığı Sayfası