Bitvisa operationer Bitvisa operationer Binärt komplement Negativa

Bitvisa operationer
Bitvisa operationer
• Alla variabler oavsett typ representeras internt i
datorn som binära tal med ettor och nollor.
• Om vi antar att en int representeras med 2 byte
(dock vanligare med 4 byte) på systemet. blir den
binära representationen:
00000000 00000001
1·20=1
00000000 00000111
1·22+1·21+1·20=7
00000000 00001000
1·23+0·22+0·21+0·20 =8
00000000 00001001
1·23+0·22+0·21+1·20 =9
Programmeringsteknik för ing
• I C kan man operera direkt på de enskilda bitarna
med de så kallade bitoperatorerna.
unary complement ˜
and
&
exclusive or
ˆ
inclusive or
|
Shiftoperatorer
left shift
<<
right shift
>>
• Bitvisa operatorer kan enbart utföras på
heltalstyper (int, unsigned int, long,
char, . . . ).
Logiska operatorer
176
Programmeringsteknik för ing
177
Binärt komplement
Negativa tal
• Med komplementet menas att alla bitar byter
värde, dvs alla ettor blir nollor och alla nollor blir
ettor.
• Den binära representationen av heltalet int a =
• Negativa tal representeras ofta enligt vad som på
engelska kallas ”two’s complement
representation”.
• Det innebär att ett negativt tal -n representeras
som det binära komplementet till n-1
550055;
(20+ 21+
22+ 25+ 27+ 210+ 213+ 214+ 219)
är
0
-1
6
-7
0000000 00001000 01100100 10100111
Uttrycket ˜a blir således
1111111 11110111 10011011 01011000
Programmeringsteknik för ing
00000000
11111111
00000000
11111111
178
aˆb
0
1
1
0
Uttryck
a
b
a&b
aˆb
a|b
˜(a | b)
(˜a & ˜b)
a|b
0
1
1
1
Programmeringsteknik för ing
00000000
11111111
00000110
11111001
179
Logiska bitvisa binära
operationer
• Tabellen visar and (&), exclusive or (ˆ) och
inclusive or (|) på 1-bits fält.
b a&b
0
0
0
0
1
0
1
1
00000000
11111111
00000000
11111111
Programmeringsteknik för ing
Logiska bitvisa binära
operationer
a
0
1
0
1
00000000
11111111
00000000
11111111
180
Representation
00000001 01001101
11111100 11110111
00000000 01000101
11111101 10111010
11111101 11111111
00000010 00000000
00000010 00000000
Programmeringsteknik för ing
Värde
333
-777
69
-582
-513
512
512
181
1
Shiftoperatorer
Fler bitoperatorer
• De två operatorerna till shiftoperatorerna måste
vara av heltalstyp.
• Uttrycket
• På samma sätt som +=, *= operatorerna finns
även dessa operatorer:
operator
exempel
ekvivalent
expr1 << expr2
>>=
<<=
ˆ=
&=
|=
innebär att bitrepresentationen i expr1 shiftas
expr2 steg till vänster.
int d=1076;
1076
d << 1;
2152
d << 3;
8608
d << 29; -2147483648
d << 32;
0
00000000
00000000
00000000
10000000
00000000
00000000
00000000
00000000
00000000
00000000
00000100
00001000
00100001
00000000
00000000
00110100
01101000
10100000
00000000
00000000
a >>= b
a <<= b
aˆ= b
a &= b
a |= b
a
a
a
a
a
=
=
=
=
=
a
a
a
a
a
>> b
<< b
ˆ b
& b
| b
• Vid vänstershift fylls 0:or på från vänster
Programmeringsteknik för ing
182
Exempel
• En uppräkningsbar typ specificerar en mängd
heltalskonstanter med symboliska namn.
• Variabler av den uppräkningsbara typen kan
endast anta värden av dessa symboliska namn.
enum state {off, on};
enum state lightbulb = on;
if (lightbulb == on)
printf("The light is on");
184
Uppräkningstyper
Programmeringsteknik för ing
185
Uppräkningstyper
• Varje symbol i typen antar ett heltal 1 större än
föregående och börjar med 0.
• Specifika heltalsvärden kan anges vid
deklarationen.
• Uppräkningstyper används ofta tillsammans med
typedef för att skapa en ny datatyp som enkelt
kan användas som funktionsparametrar m.m.
typedef enum {unknown=0,
metanol=1,
etanol=2,
butanol=4,
hexanol=6} alcohole;
int hydrogen_atoms(alcohole molecule);
...
enum boolean {false, true};
/* false = 0, true = 1 */
enum result {unknown=0, win=1, lost, tie=4};
/* unknown=0, win=1, lost=2, tie=4 */
• OBS! Det går inte att ”läsa in” värden till en
variabel typ av enum
Programmeringsteknik för ing
183
Uppräkningstyper
void bit_print(unsigned in)
{
unsigned mask=1<<8*sizeof(in)-1;
while(mask)
{
printf("%d",mask&in?1:0);
mask=mask>>1;
}
}
Programmeringsteknik för ing
Programmeringsteknik för ing
186
Programmeringsteknik för ing
187
2
Uppräkningstyper
• Eftersom uppräkningstyper är av konstant
heltalstyp kan de med fördel användas i switchsatser.
char *molecule_to_string(alcohole molecule){
switch(molecule) {
case metanol:
return "CH3OH";
case etanol:
return "C2H5OH";
case butanol:
return "C4H9OH";
case hexanol:
return "C6H13OH";
default:
return NULL;
}
Programmeringsteknik för ing
}
188
3