CHAR_BIT nedir?


93

Http://graphics.stanford.edu/~seander/bithacks.html adresinden dallanmadan tamsayı mutlak değeri (abs) hesaplamak için kodun alıntılanması :

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;

Patentli varyasyon:

r = (v ^ mask) - mask;

Nedir CHAR_BITve nasıl kullanılır?

Yanıtlar:


0

Bu kodun, işaretli türlerdeki doğru bit kaydırmanın uygulama tanımlı davranışına bağlı olduğunu bilmelisiniz. gcc her zaman mantıklı davranışı (işaret-bit-uzantısı) vermeyi vaat eder, ancak ISO C uygulamanın üst bitleri sıfır doldurmasına izin verir.

Bu sorunu aşmanın bir yolu:

#ifdef HAVE_SIGN_EXTENDING_BITSHIFT
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
#else
int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);
#endif

Kişisel Makefileveya config.hvb tanımlayabilir HAVE_SIGN_EXTENDING_BITSHIFTplatformunuza bağlı olarak yapı anda.


124
Çok ilginç bir yorum olsa da soruyu cevaplamadığı için bunun nasıl kabul edilmiş bir cevap olabileceğini anlamıyorum.
qdii

16
@Mauris: Biri soruyu düzenledi ve bir alt soruyu soru başlığına yükseltti. Orijinal başlık kuşkusuz berbattı, ancak OP'nin sorusu, alıntılanan bit hack kodunun nasıl çalıştığı ile ilgiliydi ve "en azından taşınabilir bir şekilde değil, ve işte nedeni" yararlı bir cevap.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

12
Ah, anlıyorum. Maalesef bu soru, "Nedir CHAR_BIT?" İçin Google Arama sonuçlarında çok üst sıralarda görünüyor. , asıl soru bu olmasa bile. :( Açıklamanız göz önüne alındığında, bu cevabı neden yazdığınızı anlıyorum, ancak gelecek için ya (a) cevabınızı kaldırıp soruya yorum olarak yeniden yazmak, böylece @ AraK'ın en üstte görünmesi için ya da (b) cevabınızı sorunun mevcut başlığını cevaplayacak şekilde düzenleyin.
Lynn

1
OP'nin orijinal sorusu ile editörün yorumu arasındaki niyet (ler) deki farklılığa bağlı olarak, orijinal talebin doğası istemsiz olarak değişmiş gibi görünmektedir. Her iki sorunun da (orijinal ve düzenlenmiş) değeri olsa da, bu tutarsızlığın ele alınması gerekir. Şimdi soruyorum: Bu cevap bir wiki'ye eklenebilir mi? Bu, orijinal soruyla ilgili olmasa da, bu tür bilgileri arayan kişilere yardımcı olabilir. Bundan sonra, soru dato datuashvili'nin orijinal isteğine uyacak şekilde yeniden düzenlenebilir. Sadece ilgili bir okuyucu ...

2
Bu sorunun geçmişine baktım ve asıl soru aslında kodun nasıl çalıştığını hiçbir yere sormuyor. Editörün başlığa yükselttiği soru, oradaki tek gerçek sorudur.
2017

230

CHAR_BITiçindeki bit sayısıdır char. Bugünlerde neredeyse tüm mimariler bayt başına 8 bit kullanıyor, ancak bu her zaman böyle değil. Eskiden bazı eski makinelerde 7 bit bayta sahipti.

İçinde bulunabilir <limits.h>.


3
Bazı DSP'lerin 10 veya daha fazla bit baytı vardır.
Juri Robl

65
C CHAR_BIT>=8, genellikle 32 bit olan yalnızca tek bir tür boyutuna sahip olan DSP'ler için çok daha büyük değerler gerektirir ve buna izin verir. POSIX gerektirir CHAR_BIT==8. Genel olarak, herhangi bir çok kullanıcılı / çok görevli sunucu odaklı veya etkileşimli kullanım odaklı mimariyi, internete bağlanma veya dış dünya ile metinsel veri alışverişinde bulunma şansı ile varsayabilirsiniz CHAR_BIT==8.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

6
@caf: Hayır, C99 türleri int8_tve var uint8_tolmayı gerektiriyor . Böylece bir tür genişlik 8 vardır. sizeofHerhangi bir tür ile uyumlu olması gerektiğinden, sizeof charaslında 1 sizeof int8_tolmalıdır. Yani CHAR_BIT == 8. Burada bu obezervasyonla ilgili bir şey yazdım: gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-byte
Jens Gustedt

22
@Jens Gustedt: Lütfen C99 spesifikasyonundaki bir bölümden alıntı yapın. Tam genişlikli tam sayı türlerinden C99 spesifikasyonu "Bu türler isteğe bağlıdır" der. (7.18.1.1/3) Bununla birlikte, minimum genişlik ve en hızlı genişlik türleri gereklidir.
jamesdlin

3
@jamesdlin & caf: işleri karıştırdığım için üzgünüm. evet bahsettiğim gereksinim aslında POSIX'ten geliyor stdint.h. Bu yüzden orada gereklidir ve aynı zamanda standardın belirli bir versiyonuna atıfta bulunmadan ISO C standardının Uzantısı olarak işaretlenmiştir . Benim hatam.
Jens Gustedt

2

Orijinal soruda hem açık soruyu (CHAR_BIT nedir) hem de örtük soruyu (bu nasıl çalışır) yanıtlamaya çalışıyorum.


C ve C ++ 'daki bir karakter, C programının adresleyebileceği en küçük bellek birimini temsil eder *

C ve C ++ 'daki CHAR_BIT, bir karakterdeki bit sayısını temsil eder. Karakter türündeki diğer gereksinimler nedeniyle her zaman en az 8 olmalıdır. Uygulamada, tüm modern genel amaçlı bilgisayarlarda tam olarak 8'dir, ancak bazı tarihi veya uzman sistemler daha yüksek değerlere sahip olabilir.

Java'nın CHAR_BIT veya sizeof eşdeğeri yoktur, Java'daki tüm ilkel türler sabit boyutta olduğundan ve nesnelerin iç yapısı programcıya opak olduğundan buna gerek yoktur. Bu kodu Java'ya çeviriyorsanız, "sizeof (int) * CHAR_BIT - 1" sabit değerini 31 ile değiştirebilirsiniz.

Bu özel kodda, bir int'teki bit sayısını hesaplamak için kullanılmaktadır. Bu hesaplamanın int türünün herhangi bir dolgu biti içermediğini varsaydığını unutmayın.

Derleyicinizin işaretli sayıların bit kaymalarını genişletmeyi seçtiğini ve sisteminizin negatif sayılar için 2s tamamlayıcı gösterimi kullandığını varsayarsak, bu "MASK" ın pozitif veya sıfır değer için 0 ve negatif bir değer için -1 olacağı anlamına gelir.

İkili tümleme sayısını olumsuzlamak için bit düzeyinde değil yapmalı ve sonra bir tane eklemeliyiz. Eşit bir şekilde bir tane çıkarabilir ve sonra onu bitler halinde olumsuzlayabiliriz.

Yine, iki tamamlayıcı temsilinin -1'in tümü tarafından temsil edildiğini varsayarsak, bu nedenle dışlayıcı veya -1 ile bitsel olumsuzlamaya eşittir.

Yani v sıfır olduğunda sayı yalnız bırakılır, v bir olduğunda olumsuzlanır.

Dikkat edilmesi gereken bir şey, C ve C ++ 'daki işaretli taşmanın tanımsız bir davranış olduğudur. Bu nedenle, bu ABS uygulamasını en negatif değerde kullanmak tanımsız davranışa yol açar. Bu, programın son satırının işaretsiz int olarak değerlendirileceği şekilde yayınlar eklenerek düzeltilebilir.

* Bu genellikle donanımın adresleyebileceği en küçük bellek birimiyle aynı değildir, ancak esasen aynı değildir. Bir uygulama, potansiyel olarak birden çok donanım adreslenebilir bellek birimini bir program adreslenebilir bellek biriminde birleştirebilir veya bir donanım adreslenebilir bellek birimini birden çok program eklenebilir bellek birimine bölebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.