My Project
|
Defines interface of field.c functions (do not modify) More...
#include <stdbool.h>
Go to the source code of this file.
Functions | |
int | getBit (int value, int position) |
int | setBit (int value, int position) |
int | clearBit (int value, int position) |
int | getField (int value, int hi, int lo, bool isSigned) |
int | setField (int oldValue, int hi, int lo, int newValue) |
This file defines the interface to a C file field.c that you will complete. You will learn how to use the C language operators for binary and (&), binary or (|), and binary not (~). You will also use the C language bit shift operators (<< and >>).
Binary and (&) will be used to extract the value of a bit and to set a bit to 0. This relies on the fact that the binary and (&) of a value and 1 results in the original value. Binary and (&) of a value and 0 results in 0. Binary or (|) is use to set a bit to 1. This relies on the the fact that binary or (|) of 1 and anything results in a 1.
You will create masks. A mask is a bit pattern that contains 0's and 1's in appropriate places so when the binary and/or operation is performed, the result has extracted/modified the bits of interest. In the following examples B stands for bits of interest while x stands for a bit that is not of interest. Note that, in general, the bits of interest need not be consecutive. In this code, we will be dealing with consecutive sets of bits.
value: xxxBBBBxxxxx value: xxxBBBBxxxxx value: xxxBBBBxxxxx
mask: 000111100000 mask: 111000011111 mask: 000111100000
------- ------------ ------------ ------------
and(&) 000BBBB0000 and(&) xxx0000xxxxx or(|) xxx1111xxxxx
result: isolate field clear field set field
You may create masks on the fly using C code, or you may pre compute masks and store them in an array and just use the one you need. Note the mask for clearing bits is the binary not (~) of the mask for extracting bits.
Bit positions are numbered from 31 to 0 with 0 being the least significant bit. The bit position corresponds to the power of 2 in the binary representation.
As an example of how the fields interface is useful consider the IEEE half precision floating point representation. In the IEEE half precision floating point representation, 16 bits are used to represent a floating point number. This is shown in the following table where S represents the sign, E represents bits for the exponent, and F represents bits for the fraction.
bit position | 31..16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
meaning | not used | S | E | E | E | E | E | F | F | F | F | F | F | F | F | F | F |
To extract fields from the value, you would make calls like:
int sign = getField(value, 15, 15, 0);
int exp = getField(value, 14, 10, 0);
int frac = getField(value, 9, 0, 0);
In the following methods, hi and lo are guaranteed to be ordered, and within the range 0..31, so no error checking is required.
int clearBit | ( | int | value, |
int | position | ||
) |
int getBit | ( | int | value, |
int | position | ||
) |
int getField | ( | int | value, |
int | hi, | ||
int | lo, | ||
bool | isSigned | ||
) |
Extract the field (possibly signed) between bits hi and lo (inclusive).
value | the source value or bit pattern |
hi | the bit position of one end of the field |
lo | the bit position of the other end of the field |
isSigned | false means the field is unsigned, true means the field is signed |
int setBit | ( | int | value, |
int | position | ||
) |
int setField | ( | int | oldValue, |
int | hi, | ||
int | lo, | ||
int | newValue | ||
) |
Change the bits of oldValue between hi and lo to the newValue, leaving the other bits unchanged.
oldValue | the original value |
hi | the bit position of one end of the field |
lo | the bit position of the other end of the field |
newValue | the new value to put in the field (use lower bits) |