Jawaban:
Jika Anda menginginkan bit k-th dari n, lakukan
(n & ( 1 << k )) >> k
Di sini kita membuat mask, menerapkan mask ke n, lalu geser ke kanan nilai mask untuk mendapatkan sedikit yang kita inginkan. Kita dapat menuliskannya lebih lengkap sebagai:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Anda dapat membaca lebih lanjut tentang bit-masking di sini .
Berikut adalah programnya:
#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
juga dapat berguna, karena Anda mendapatkan semua data yang diperlukan dengan satu operasi.
Seperti yang diminta, saya memutuskan untuk memperpanjang komentar saya pada jawaban telunjuk menjadi jawaban yang lengkap. Meskipun jawabannya benar, itu sangat rumit. Selanjutnya semua jawaban saat ini menggunakan tanda int
s untuk mewakili nilai. Ini berbahaya, karena pergeseran kanan dari nilai-nilai negatif ditentukan oleh implementasi (yaitu tidak portabel) dan pergeseran ke kiri dapat menyebabkan perilaku yang tidak ditentukan (lihat pertanyaan ini ).
Dengan menggeser bit yang diinginkan ke kanan ke posisi bit yang paling tidak signifikan, masking dapat dilakukan dengan 1
. Tidak perlu menghitung nilai topeng baru untuk setiap bit.
(n >> k) & 1
Sebagai program lengkap, menghitung (dan kemudian mencetak) larik nilai bit tunggal:
#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);
}
Dengan asumsi bahwa Anda ingin menghitung semua bit seperti dalam kasus ini, dan bukan bit tertentu, loop dapat diubah lebih lanjut menjadi
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Ini memodifikasi input
di tempat dan dengan demikian memungkinkan penggunaan lebar konstan, pergeseran bit tunggal, yang mungkin lebih efisien pada beberapa arsitektur.
Berikut salah satu cara untuk melakukannya — ada banyak cara lainnya:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Sulit untuk memahami mengapa penggunaan loop tidak diinginkan, tetapi cukup mudah untuk membuka loop:
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));
Atau mengevaluasi ekspresi konstanta dalam empat pernyataan terakhir:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
Berikut cara yang sangat sederhana untuk melakukannya;
int main()
{
int s=7,l=1;
vector <bool> v;
v.clear();
while (l <= 4)
{
v.push_back(s%2);
s /= 2;
l++;
}
for (l=(v.size()-1); l >= 0; l--)
{
cout<<v[l]<<" ";
}
return 0;
}
@prateek terima kasih atas bantuannya. Saya menulis ulang fungsi dengan komentar untuk digunakan dalam sebuah program. Tingkatkan 8 untuk lebih banyak bit (hingga 32 untuk bilangan bulat).
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;
}
Jika Anda tidak menginginkan loop apa pun, Anda harus menuliskannya:
#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;
}
Seperti yang ditunjukkan di sini, ini juga berfungsi di penginisialisasi.
Menggunakan std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
sama validnya dan tidak perlu menghitung topeng karena topengnya konstan karena bergeser sebelum menutupi alih-alih sebaliknya.