Yanıtlar:
K'inci n'yi istiyorsanız, yapın
(n & ( 1 << k )) >> k
Burada bir maske oluşturuyoruz, maskeyi n'ye uyguluyoruz ve sonra tam istediğimiz biti elde etmek için maskelenmiş değeri sağa kaydırıyoruz. Bunu daha eksiksiz bir şekilde yazabiliriz:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Sen bit maskeleme hakkında daha fazla bilgi bulabilirsiniz burada .
İşte bir program:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
struct
gerekli tüm verileri tek bir işlemle elde ettiğiniz için verileri bir a üzerine aktarmak da yararlı olabilir.
İstendiği gibi, işaret parmağının cevabı hakkındaki yorumumu tam teşekküllü bir cevaba genişletmeye karar verdim. Cevabı doğru olsa da gereksiz yere karmaşıktır. Ayrıca tüm mevcut cevaplar int
, değerleri temsil etmek için işaretli s kullanır. Negatif değerlerin sağa kaydırılması uygulama tanımlı olduğundan (yani taşınabilir değil) ve sola kaydırma tanımsız davranışa yol açabileceğinden ( bu soruya bakın) bu tehlikelidir .
İstenilen biti en az anlamlı bit konumuna sağa kaydırarak, maskeleme yapılabilir 1
. Her bit için yeni bir maske değeri hesaplamaya gerek yoktur.
(n >> k) & 1
Tam bir program olarak, bir dizi tek bitlik değerleri hesaplamak (ve ardından yazdırmak):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
Bu durumda olduğu gibi tüm bitleri hesaplamak istediğinizi ve belirli bir biti hesaplamak istemediğinizi varsayarsak, döngü daha sonra şu şekilde değiştirilebilir:
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Bu input
, yerinde değişiklik yapar ve böylece, bazı mimarilerde daha verimli olabilecek sabit genişlikte, tek bit kaymasının kullanımına izin verir.
İşte bunu yapmanın bir yolu - başka birçok yöntem var:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Bir döngü kullanımının neden istenmediğini anlamak zordur, ancak döngüyü açmak yeterince kolaydır:
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
Veya son dört ifadedeki sabit ifadeleri değerlendirmek:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
@prateek yardımlarınız için teşekkür ederim. Fonksiyonu bir programda kullanılmak üzere yorumlarla yeniden yazdım. Daha fazla bit için 8'i artırın (bir tam sayı için 32'ye kadar).
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
Herhangi bir döngü istemiyorsanız, yazmanız gerekir:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
Burada gösterildiği gibi, bu aynı zamanda bir başlatıcıda da çalışır.
Kullanma std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
eşit derecede geçerlidir ve tam tersi yerine maskelemeden önce kayma nedeniyle maske sabit olduğundan maskenin hesaplanmasını gerektirmez.