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