Positive Values Have 0 in Left-Most Bit

Positive Values Have 0 in Left-Most Bit

CSE230

Bitwise Operators

Enumeration Type

Struct & Union

2’s Complement Notation

•Positive values have 0 in left-most bit.

•To negate a positive value, complement (“flip”) each bit and then add 1 to the result.
(Negative values have 1 in the left-most bit.)

•Example:
010101012 = +8510
Complement each bit:101010102
Add 1:101010112 = -8510

Bitwise Operators

•~ bitwise complement (1’s complement)

•bitwise AND

•| bitwise OR

•^ bitwise XOR (exclusive OR)

•left shift

•right shift

Logical Operators

short int a = 0x1234,
b = 0x5678,
c = 0x9abc;

printf(“%x\n%x\n%x\n%x\n%x\n”,

~a,a & b, a | b, a ^ b,a & b | c);

Shift Operators

short int a = 0x1234,
b = 0x5678;

unsigned shortc = 0x9abc;

d = 0xdef0;

printf(“%x\n%x\n%x\n%x\n”,

a < 4,b < 6,c > 3,d > 3);

Masking

•The bitwise-AND operator is often used to mask out specific bits of an integer value.

•Example:
int is_odd(int num)
{
int mask = ______;
return (______);
}

Example (page 338)

#include <limits.h>

void bit_print(int a) {
int i;
int n = sizeof(int) * CHAR_BIT;
int mask = 1 < (______);
for (i = 1; i <= n; ++i) {
putchar(((______) ? ‘0’:‘1’);
a <= 1;
}

} Data Compression

•Bitwise operators can be used to pack data and unpack data.

•PACK - store small data units in large unit

•UNPACK - extract small data units from
large unit

Packing (page 341)

#include <limits.h>

int pack(char a, char b, char c, char d) {
int p = a;
p = (p < CHAR_BIT) | ______;
p = (p < CHAR_BIT) | ______;
p = (p < CHAR_BIT) | ______;
return p;

}

Unpacking

#include <limits.h>

char *unpack(int p) {
char c[4];
c[0] = (p & 0x______) > _____ ;
c[1] = (p & 0x00ff0000) > 16 ;
c[2] = (p & 0x0000ff00) > _____ ;
c[3] = (p & 0x000000ff) ;
return c;

}

Data Record Storage

•Zip Code - 5 digits => _____ bits

•Resident gender - M/F => _____ bit

•First letter of last name=> _____ bits

•Birthday month => _____ bits

•Birthday day=> _____bits
______
32 bits (int)

Example

int make_record(int zipcode,
char gender, char lastname,
int birthmonth, int birthday) {
int record = 0;
record |= zipcode;
record |= ((gender =‘M’) ? ______) < _____;
record |= (lastname - ‘A’ + 1) < _____;
record |= birthmonth < ______;
record |= birthday < ______;
return record;

}

Bit Fields

struct person{

unsigned zip_code:______;

unsigned gender:______;

unsigned first_letter:______;

unsigned birthmonth:_____;

unsigned birthday:______;

};

Access: struct person r;

r.zip_code = 11794;

r.gender = 0;

r.birthday = 30;

Bit Fields (cont’d)

typedef struct { unsigned

zip_code:______,

gender:______,

first_letter:______,

birthmonth:______,

birthday:______;

} person_type;

Access: person_type r;

r.zip_code = 11794; r.gender = 0;

r.birthday = 30;

Arrays of Structs

struct { unsigned

b0:1, b1:1, b2:1, b3:1, b4:1,
b5:1, b6:1, b7:1, b8:1, b9:1,
b10:1, b11:1, b12:1, b13:1, b14:1,
b15:1, b16:1, b17:1, b18:1, b19:1,
b20:1, b21:1, b22:1, b23:1, b24:1,
b25:1, b26:1, b27:1, b28:1, b29:1,
b30:1, b31:1;

} word[1000];

Access: word[34].b5

Enumeration Types

•An enumerated data type is an ordinal data type that lists the valid data values for a variable of this data type.

•The values of the enumerated data type are constants of type int.

•The integer value of the first element of the enumerated data type is 0 by default.

•The values of the enumerated data type elements can be reassigned.

Syntax

enum day {sun, mon, tues, wed, thur, fri, sat};

enum day {sun=____, mon, tues, wed, thur, fri, sat};

enum day {sun=____, mon, tues, wed, thurs=_____, fri, sat};

/* Defining variables */

enum day today, tomorrow, yesterday;

More Syntax

enum weather {sunny, cloudy, rain, snow, thunder, windy} forecast1;

enum {sunny, cloudy, rain, snow, thunder, windy} forecast2;

forecast1 = snow;

if (______)
printf(“Hold on to your hat.\n”);

Example

enum day {sun, mon, tue, wed, thu, fri, sat};

typedef enum day day;

day next_day(day d) {
if (______) return sun;
else return (day)(______);

}

Example: POKER

•Five cards

•Each card has a suit and a value

•Suits: clubs, diamonds, hearts, spades

•Values: ace, 2, 3, ..., 10,
jack (11), queen (12), king (13)

•Ace can be treated as “high” (14) or
“low” (1)

POKER hands

•Straight Flush78910J

•Four of a Kind33 33Q

•Full House6 6 6KK

•FlushA2 4 8J

•Straight45678

•Three of a KindA7QQQ

•Two Pair5599J

•PairA241010

•High Card247JK

Storage of Poker Cards

enum suit {hearts, diamonds, clubs, spades};

enum value {ace=1, two, three, four,
five, six, seven, eight, nine, ten, jack, queen, king};

typedef enum suit suit

typedef enum value value

suit cardsuit[5];

value cardval[5];

Storage of Poker

•Each card can be stored as a struct with two fields: value and suit.

•An array of cards is simply an array of these structs:
struct card {

suit pip;

value rank;

} cards[5];

. . . .

cards[1].rank = ace;

cards[1].pip = clubs;

CardsStraight Flush

int is_straight_flush(suit cardsuit[], int cardval[])

{
if (______(cardsuit, cardval) & ______(cardsuit,

cardval))
return 1;
else return 0;

}

Unions

•A struct that allows one field to have different names and storage types.

•Union can only store one value at a time.

•Example:
union road {
int route_num;
char name[20];
} highway;
highway.route_num = ______;
highway.name = ______;

Unions (cont’d)

•Another example:
union road {
int route_num;
char name[20];
} highways[100];

highways[10].name=______;

highways[10].route_num = ______;

printf(“%c”,highways[10].name[0]);

1