Loading lang_c_09_bitwise...
#include <stdio.h>
void test_shift(void) { printf("\n~~~~ %s() ~~~~\n", __func__); }
int main(void) { test_shift(); return 0; }
expr<<Net
expr>>Nprovoquent respectivement le décalage de N bits vers la gauche (les poids forts) et vers la droite (les poids faibles) de l'expression expr✍
{ ... uint32_t values[]={12, 23, 34, 45, 56}; int count=(int)(sizeof(values)/sizeof(values[0])); for(int i=0; i<count; ++i) { uint32_t value=values[i]; for(int shift=0; shift<4; ++shift) { uint32_t ls=value<<shift, rs=value>>shift; printf("%u << %d = %u\t%u >> %d = %u\n", value, shift, ls, value, shift, rs); } } ... }
inline static uint32_t Word32_one(int bit) { return 1u<<bit; }
{ ... for(int i=0; i<32; ++i) { printf("bit %d --> %u\n", i, Word32_one(i)); } ... }
c=a&b; // bitwise AND c=a|b; // bitwise OR c=a^b; // bitwise X-OR a7 a6 a5 a4 a3 a2 a1 a0 a7 a6 a5 a4 a3 a2 a1 a0 a7 a6 a5 a4 a3 a2 a1 a0 & b7 b6 b5 b4 b3 b2 b1 b0 | b7 b6 b5 b4 b3 b2 b1 b0 ^ b7 b6 b5 b4 b3 b2 b1 b0 ─────────────────────── ─────────────────────── ─────────────────────── c7 c6 c5 c4 c3 c2 c1 c0 c7 c6 c5 c4 c3 c2 c1 c0 c7 c6 c5 c4 c3 c2 c1 c0 ( avec ci = ai & bi ) ( avec ci = ai | bi ) ( avec ci = ai ^ bi )Comme explicité sur cette illustration (qui se limite à des entiers de huit bits pour réduire l'écriture), ces opérations consistent à appliquer individuellement l'opération logique sur chaque paire de bits qui sont en même position dans chacun des deux opérandes.
c=a&&b;est équivalente à
c=(a!=0)&&(b!=0) ? true : false;alors que l'opération bit-à-bit
c=a&b;peut produire toute une variété de valeurs,
c=a||b;est équivalente à
c=(a!=0)||(b!=0) ? true : false;alors que l'opération bit-à-bit
c=a|b;peut produire toute une variété de valeurs.
void test_bitwise(void) { printf("\n~~~~ %s() ~~~~\n", __func__); uint32_t values[]={12, 23, 34, 45, 56}; int count=(int)(sizeof(values)/sizeof(values[0])); uint32_t prev=0; for(int i=0; i<count; ++i) { uint32_t value=values[i]; printf(" %u & %u = %u\n", value, prev, value&prev); printf(" %u | %u = %u\n", value, prev, value|prev); printf(" %u ^ %u = %u\n", value, prev, value^prev); prev=value; } }
inline static bool Word32_test(uint32_t value, int bit) { uint32_t mask=Word32_one(bit); return value&mask; }
{ ... uint32_t value=values[i]; printf("%u: ", value); for(int j=0; j<32; ++j) { if(Word32_test(value, j)) { printf("%d ", j); } } printf("\n"); ... }
a&=b,
c|=det
e^=fsont respectivement équivalentes à
a=a&b,
c=c|det
e=e^f.
#define BIT_ZERO_CHAR '.' #define BIT_ONE_CHAR 'X'
void Word32_dump(char *pattern, uint32_t value) { for(int i=0; i<32; ++i) { pattern[i]=Word32_test(value, 31-i) ? BIT_ONE_CHAR : BIT_ZERO_CHAR; } }
void test_dump_load(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; for(uint32_t i=0; i<40; ++i) { Word32_dump(pattern, i); printf("%s\t%u\n", pattern, i); } }
inline static void Word32_set(uint32_t *inout_value, int bit) { uint32_t mask=Word32_one(bit); *inout_value|=mask; }
uint32_t Word32_load(const char *pattern) { uint32_t result=0; for(int i=0; i<32; ++i) { if(pattern[i]==BIT_ONE_CHAR) { Word32_set(&result, 31-i); } } return result; }
{ ... Word32_dump(pattern, i); uint32_t check=Word32_load(pattern); printf("%s\t%u\t%u\n", pattern, i, check); ... }
if(value&(1u<<N)) { ... },
value|=(1u<<N);.
b=!a;est équivalente à
b=(a==0) ? true : false;alors que le complément bit-à-bit
b=~a;peut produire toute une variété de valeurs. Pour constater l'effet de cet opérateur, il faut réaliser la fonction test_complement() dans le fichier prog09.c.
void test_complement(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; uint32_t v1=9876, v2=~v1; Word32_dump(pattern, v1); printf("v1: %s\t%u\n", pattern, v1); Word32_dump(pattern, v2); printf("v2: %s\t%u\n", pattern, v2); }
inline static void Word32_clear(uint32_t *inout_value, int bit) { uint32_t mask=Word32_one(bit); *inout_value&=~mask; }
{ ... uint32_t v3=~0u; for(int i=0; i<32; ++i) { if(Word32_test(v1, i)) { Word32_clear(&v3, i); } } Word32_dump(pattern, v3); printf("v3: %s\t%u\n", pattern, v3); ... }
value&=~(1u<<N);.
void test_signed(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; int32_t v1=9876, v2=-v1, v3=~v1; Word32_dump(pattern, (uint32_t)v1); printf("v1: %s\t%d\n", pattern, v1); Word32_dump(pattern, (uint32_t)v2); printf("v2: %s\t%d\n", pattern, v2); Word32_dump(pattern, (uint32_t)v3); printf("v3: %s\t%d\n", pattern, v3); }
inline static uint32_t Word32_negate(uint32_t value) { return 1+~value; }
{ ... int32_t v4=(int32_t)Word32_negate((uint32_t)v1); Word32_dump(pattern, (uint32_t)v4); printf("v4: %s\t%d\n", pattern, v4); ... }
{ ... int32_t v5=v1>>2, v6=v2>>2; Word32_dump(pattern, (uint32_t)v5); printf("v5: %s\t%d\n", pattern, v5); Word32_dump(pattern, (uint32_t)v6); printf("v6: %s\t%d\n", pattern, v6); ... }
{ ... uint32_t v7=((uint32_t)v2)>>2; Word32_dump(pattern, v7); printf("v7: %s\t%d\n", pattern, v7); ... }
<<=,
>>=,
&=,
|=,
^=) tout comme dans le cas des opérations arithmétiques usuelles (
+=,
-=,
*=,
/=,
%=).
<<) ou les poids faibles (
>>), leur combinaison selon des opérations et (
&), ou (
|) ou ou-exclusif (
^) ou encore leur complémentation (
~).
//----------------------------------------------------------------------------
#ifndef WORD32_H #define WORD32_H
#include <stdint.h> #include <stdbool.h>
inline static uint32_t Word32_one(int bit) { return 1u<<bit; }
inline static bool Word32_test(uint32_t value, int bit) { uint32_t mask=Word32_one(bit); return value&mask; }
inline static void Word32_set(uint32_t *inout_value, int bit) { uint32_t mask=Word32_one(bit); *inout_value|=mask; }
inline static void Word32_clear(uint32_t *inout_value, int bit) { uint32_t mask=Word32_one(bit); *inout_value&=~mask; }
inline static uint32_t Word32_negate(uint32_t value) { return 1+~value; }
void Word32_dump(char *pattern, uint32_t value);
uint32_t Word32_load(const char *pattern);
#endif // WORD32_H
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#include "word32.h"
#define BIT_ZERO_CHAR '.' #define BIT_ONE_CHAR 'X'
void Word32_dump(char *pattern, uint32_t value) { for(int i=0; i<32; ++i) { pattern[i]=Word32_test(value, 31-i) ? BIT_ONE_CHAR : BIT_ZERO_CHAR; } }
uint32_t Word32_load(const char *pattern) { uint32_t result=0; for(int i=0; i<32; ++i) { if(pattern[i]==BIT_ONE_CHAR) { Word32_set(&result, 31-i); } } return result; }
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#include <stdio.h> #include "word32.h"
void test_shift(void) { printf("\n~~~~ %s() ~~~~\n", __func__); uint32_t values[]={12, 23, 34, 45, 56}; int count=(int)(sizeof(values)/sizeof(values[0])); for(int i=0; i<count; ++i) { uint32_t value=values[i]; for(int shift=0; shift<4; ++shift) { uint32_t ls=value<<shift, rs=value>>shift; printf("%u << %d = %u\t%u >> %d = %u\n", value, shift, ls, value, shift, rs); } } for(int i=0; i<32; ++i) { printf("bit %d --> %u\n", i, Word32_one(i)); } }
void test_bitwise(void) { printf("\n~~~~ %s() ~~~~\n", __func__); uint32_t values[]={12, 23, 34, 45, 56}; int count=(int)(sizeof(values)/sizeof(values[0])); uint32_t prev=0; for(int i=0; i<count; ++i) { uint32_t value=values[i]; printf("%u: ", value); for(int j=0; j<32; ++j) { if(Word32_test(value, j)) { printf("%d ", j); } } printf("\n"); printf(" %u & %u = %u\n", value, prev, value&prev); printf(" %u | %u = %u\n", value, prev, value|prev); printf(" %u ^ %u = %u\n", value, prev, value^prev); prev=value; } }
void test_dump_load(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; for(uint32_t i=0; i<40; ++i) { Word32_dump(pattern, i); uint32_t check=Word32_load(pattern); printf("%s\t%u\t%u\n", pattern, i, check); } }
void test_complement(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; uint32_t v1=9876, v2=~v1; Word32_dump(pattern, v1); printf("v1: %s\t%u\n", pattern, v1); Word32_dump(pattern, v2); printf("v2: %s\t%u\n", pattern, v2); uint32_t v3=~0u; for(int i=0; i<32; ++i) { if(Word32_test(v1, i)) { Word32_clear(&v3, i); } } Word32_dump(pattern, v3); printf("v3: %s\t%u\n", pattern, v3); }
void test_signed(void) { printf("\n~~~~ %s() ~~~~\n", __func__); char pattern[33]={0}; int32_t v1=9876, v2=-v1, v3=~v1; Word32_dump(pattern, (uint32_t)v1); printf("v1: %s\t%d\n", pattern, v1); Word32_dump(pattern, (uint32_t)v2); printf("v2: %s\t%d\n", pattern, v2); Word32_dump(pattern, (uint32_t)v3); printf("v3: %s\t%d\n", pattern, v3); int32_t v4=(int32_t)Word32_negate((uint32_t)v1); Word32_dump(pattern, (uint32_t)v4); printf("v4: %s\t%d\n", pattern, v4); int32_t v5=v1>>2, v6=v2>>2; Word32_dump(pattern, (uint32_t)v5); printf("v5: %s\t%d\n", pattern, v5); Word32_dump(pattern, (uint32_t)v6); printf("v6: %s\t%d\n", pattern, v6); uint32_t v7=((uint32_t)v2)>>2; Word32_dump(pattern, v7); printf("v7: %s\t%d\n", pattern, v7); }
int main(void) { test_shift(); test_bitwise(); test_dump_load(); test_complement(); test_signed(); return 0; }
//----------------------------------------------------------------------------