How to simulate a 4-bit binary adder in C - c

My professor assigned the class to write a C program to simulate a 32-bit adder using basic adders. I know a 32-bit adder is made up of 8 X 4-bit adders. However, I am unsure even how to simulate a 4-bit adder in C. I need to implement a 4-bit binary ripple carry adder, a 4-bit binary look-ahead carry generator, and a 4-bit look-ahead carry adder. From the truth table of a full adder and a Karnaugh map, I obtained the functions of the Sum and Carry Out outputs. For Sum I received A xor B xor Carry In. For the Carry out function, I received (A*B) + (Carry in(A xor B)). Now I am unsure where to go. I'm pretty sure I need to manipulate the integers at the bit level using bitwise operators (I have basic knowledge of bitwise operators although I have never implemented them outside of paper and pencil).
How do I break the integers up to obtain the A, B and Carry In inputs for the functions? How do I obtain the Sum and Carry Out outputs? How do I string the full adders together to obtain a 4-bit adder?
Thank you for the help!

Well, for a simple solution, we can take a half adder and full adder circuit diagram and abstract it a bit. From Wikipedia:
Half Adder:
Full Adder:
#include<stdio.h>
typedef char bit;
bit carry = 0;
bit halfadd( bit A, bit B ){
carry = A & B;
return A ^ B;
}
bit fulladd( bit A, bit B ){
bit xor = A ^ B;
bit ret = carry ^ xor;
carry = (carry & xor) | (A & B);
return ret;
}
void fillNum( int num, bit *array ){
int i;
for( i = 0; i < 32; ++ i ){
array[i] = ( num >> i ) & 1;
}
}
int main(){
bit num1[32] = {0}, num2[32] = {0};
int A = 64620926, B = 1531529858;
fillNum( A, num1 );
fillNum( B, num2 );
int r = 0;
bit tmp = halfadd( num1[0], num2[0] );
putchar( tmp ? '1' : '0' );
r = tmp;
int i;
for( i = 1; i < 32; ++i ){
tmp = fulladd( num1[i], num2[i] );
r += tmp << i;
putchar( tmp ? '1' : '0' );
}
putchar( carry ? '1' : '0' );
printf("\n%d\n\n%d + %d = %d", r, A, B, A+B);
return 0;
}
That will output the added value with the LSB first, but it demonstrates the basic principal. This works according to Ideone. Just apply a similar approach to handling logic circuitry when simulating 4 bit adders.
If you don't want to read the integers to an array first, you can always use
#define GETBIT(num,bit)((num>>bit)&1)
For safety, you can put it in to a function call if you want

If I were doing this, I would simulate a 4 bit adder with a Lookup Table. In this case it would be a 256 entry table that could be setup like a 16 x 16 array of values.
unsigned short outputs[16][16];
multOut = outputs[inA][inB];
You will have to initialize your array, but that should be pretty simple.
Use the 5th bit of each value in the array as your carry out bit.

To start you will need to break your larger integers into individual bits. This will depend on the endianess of your system (whether numbers are stored most, or least significant bit first). An array of bit masks would help. Assuming big endian,
int bit[]={
1<<0, //least significant bit
1<<1,
1<<2,
1<<3
};
So then to get the first bit of a number you would do
leastSignificantBitOfA = A&bit[0];
From there you could either use some shared array to store outputs or maybe make a simple structure like:
struct fullAdderReturn{
int sum;
int carryOut;
}
struct fullAdderReturn oneBitAdder(int a, int b, int carryIn)
{
struct fullAdderReturn output;
output.sum = a&b;
output.carryOut = (a&b) | (a&carryIn) | (b&carryIn);
return output;
}
I put together a simple 2-bit ripple adder here http://ideone.com/NRoQMS hopefully it gives you some ideas .

Related

How to return multiple bits from a number in C

I have a function to extract a single bit from a number:
int getBit (int value, int position) {
return value & (1 << position));
}
But how do I do it for a range (both for signed and unsigned numbers)? For instance:
get bits 10:14 from 0x12345678 (signed 0) = 0x15
int getField (int value, int hi, int lo, bool isSigned)
I suspect you might want to approach the entire problem in a different way. Rather than extracting bits, why not just use bit masks.
For example, to check if the most significant bit in a byte is enabled:
if(byte & 0xf0) {}
To check for the least significant bit it would be:
if(byte & 0x01) {}
To check for multiple (or a "range") of bits, say the low order nibble:
if(byte & 0x0f) {}
From what you've said, I suspect this is much closer to what you want and much simpler than shifting to extract bits.
You just have to create a mask:
int createMask(int a, int b){
int c = a;
int mask = 0;
/*First we set the lenght of the mask*/
while(c <= b){ /*Including b*/
mask <<= 1;
mask = mask|1;
c++;
}
/*Then we set the position to the mask, the first bit is in the position 0*/
c=0;
while(c<a){
c++;
mask <<= 1 ;
}
return mask;
}
I haven't tested the function yet, but its just for explaining a way to make a mask.
And the final function may be something like this:
int getBits(int value, int a, int b){
int mask = createMask(a, b);
mask &= value;
//Now we have to move the bits to the right
while(a>0){
mask >>= 1;
a--;
}
return mask;
}
An example, if you want the first 6 bits, you have to code: getBits(myValue, 0, 5).
Im not sure what did you mean about the signeds and unsigneds numbers, but i hope it can help you.
Srry for my english.
That was a bit of fun :) In three easy steps:
shift your value right by the amount lo and decrease hi with lo. This simplifies the problem to 'get the lowest hi bits'.
clip off the highest bits -- a custom mask is created on the fly.
if necessary, use the highest bit to sign-extend the result (bitfiddling based on Sign extending from a constant bit width in C#).
I don't know the reason for the suggested function prototype, but I would suggest using the order lo, hi rather than hi, lo. Somehow 10,14 feels more natural than the other way around, even though bits count down from high to low, when counted left to right -- the computer is supposed to make things easier for us!
#include <stdio.h>
#include <stdbool.h>
int getField (int value, int hi, int lo, bool isSigned)
{
/* step 1: clip off lower bits */
value >>= lo;
hi -= lo-1;
/* step 2: clip off higher bits */
value &= ~(-1<<hi);
/* step 3: extend sign */
if (isSigned && (value & (1<<(hi-1))))
value |= -(1<<hi);
return value;
}
int main (void)
{
int i;
i = getField (0x123456c8, 14,10, true);
printf ("i = %d / %Xh\n", i,i);
return 0;
}
Result:
i = -11 / FFFFFFF5h
which is the correct bit set:
16 12 8 4 0 <- bit position
...4 5 6 7 8 <- value
0100 0101 0110 0111 1000 <- bitwise
--- -- <- mask
101 01 <- result
..111101 01 < sign extended result

Iterate through bits in C

I have a big char *str where the first 8 chars (which equals 64 bits if I'm not wrong), represents a bitmap. Is there any way to iterate through these 8 chars and see which bits are 0? I'm having alot of trouble understanding the concept of bits, as you can't "see" them in the code, so I can't think of any way to do this.
Imagine you have only one byte, a single char my_char. You can test for individual bits using bitwise operators and bit shifts.
unsigned char my_char = 0xAA;
int what_bit_i_am_testing = 0;
while (what_bit_i_am_testing < 8) {
if (my_char & 0x01) {
printf("bit %d is 1\n", what_bit_i_am_testing);
}
else {
printf("bit %d is 0\n", what_bit_i_am_testing);
}
what_bit_i_am_testing++;
my_char = my_char >> 1;
}
The part that must be new to you, is the >> operator. This operator will "insert a zero on the left and push every bit to the right, and the rightmost will be thrown away".
That was not a very technical description for a right bit shift of 1.
Here is a way to iterate over each of the set bits of an unsigned integer (use unsigned rather than signed integers for well-defined behaviour; unsigned of any width should be fine), one bit at a time.
Define the following macros:
#define LSBIT(X) ((X) & (-(X)))
#define CLEARLSBIT(X) ((X) & ((X) - 1))
Then you can use the following idiom to iterate over the set bits, LSbit first:
unsigned temp_bits;
unsigned one_bit;
temp_bits = some_value;
for ( ; temp_bits; temp_bits = CLEARLSBIT(temp_bits) ) {
one_bit = LSBIT(temp_bits);
/* Do something with one_bit */
}
I'm not sure whether this suits your needs. You said you want to check for 0 bits, rather than 1 bits — maybe you could bitwise-invert the initial value. Also for multi-byte values, you could put it in another for loop to process one byte/word at a time.
It's true for little-endian memory architecture:
const int cBitmapSize = 8;
const int cBitsCount = cBitmapSize * 8;
const unsigned char cBitmap[cBitmapSize] = /* some data */;
for(int n = 0; n < cBitsCount; n++)
{
unsigned char Mask = 1 << (n % 8);
if(cBitmap[n / 8] & Mask)
{
// if n'th bit is 1...
}
}
In the C language, chars are 8-bit wide bytes, and in general in computer science, data is organized around bytes as the fundamental unit.
In some cases, such as your problem, data is stored as boolean values in individual bits, so we need a way to determine whether a particular bit in a particular byte is on or off. There is already an SO solution for this explaining how to do bit manipulations in C.
To check a bit, the usual method is to AND it with the bit you want to check:
int isBitSet = bitmap & (1 << bit_position);
If the variable isBitSet is 0 after this operation, then the bit is not set. Any other value indicates that the bit is on.
For one char b you can simply iterate like this :
for (int i=0; i<8; i++) {
printf("This is the %d-th bit : %d\n",i,(b>>i)&1);
}
You can then iterate through the chars as needed.
What you should understand is that you cannot manipulate directly the bits, you can just use some arithmetic properties of number in base 2 to compute numbers that in some way represents some bits you want to know.
How does it work for example ? In a char there is 8 bits. A char can be see as a number written with 8 bits in base 2. If the number in b is b7b6b5b4b3b2b1b0 (each being a digit) then b>>i is b shifted to the right by i positions (in the left 0's are pushed). So, 10110111 >> 2 is 00101101, then the operation &1 isolate the last bit (bitwise and operator).
If you want to iterate through all char.
char *str = "MNO"; // M=01001101, N=01001110, O=01001111
int bit = 0;
for (int x = strlen(str)-1; x > -1; x--){ // Start from O, N, M
printf("Char %c \n", str[x]);
for(int y=0; y<8; y++){ // Iterate though every bit
// Shift bit the the right with y step and mask last position
if( str[x]>>y & 0b00000001 ){
printf("bit %d = 1\n", bit);
}else{
printf("bit %d = 0\n", bit);
}
bit++;
}
}
output
Char O
bit 0 = 1
bit 1 = 1
bit 2 = 1
bit 3 = 1
bit 4 = 0
bit 5 = 0
bit 6 = 1
bit 7 = 0
Char N
bit 8 = 0
bit 9 = 1
bit 10 = 1
...

Bit Rotation in C

The Problem: Exercise 2-8 of The C Programming Language, "Write a function rightrot(x,n) that returns the value of the integer x, rotated to the right by n positions."
I have done this every way that I know how. Here is the issue that I am having. Take a given number for this exercise, say 29, and rotate it right one position.
11101 and it becomes 11110 or 30. Let's say for the sake of argument that the system we are working on has an unsigned integer type size of 32 bits. Let's further say that we have the number 29 stored in an unsigned integer variable. In memory the number will have 27 zeros ahead of it. So when we rotate 29 right one using one of several algorithms mine is posted below, we get the number 2147483662. This is obviously not the desired result.
unsigned int rightrot(unsigned x, int n) {
return (x >> n) | (x << (sizeof(x) * CHAR_BIT) - n);
}
Technically, this is correct, but I was thinking that the 27 zeros that are in front of 11101 were insignificant. I have also tried a couple of other solutions:
int wordsize(void) { // compute the wordsize on a given machine...
unsigned x = ~0;
int b;
for(b = 0; x; b++)
x &= x-1;
return x;
}
unsigned int rightrot(unsigned x, int n) {
unsigned rbit;
while(n --) {
rbit = x >> 1;
x |= (rbit << wordsize() - 1);
}
return x;
This last and final solution is the one where I thought that I had it, I will explain where it failed once I get to the end. I am sure that you will see my mistake...
int bitcount(unsigned x) {
int b;
for(b = 0; x; b++)
x &= x-1;
return b;
}
unsigned int rightrot(unsigned x, int n) {
unsigned rbit;
int shift = bitcount(x);
while(n--) {
rbit = x & 1;
x >>= 1;
x |= (rbit << shift);
}
}
This solution gives the expected answer of 30 that I was looking for, but if you use a number for x like oh say 31 (11111), then there are issues, specifically the outcome is 47, using one for n. I did not think of this earlier, but if a number like 8 (1000) is used then mayhem. There is only one set bit in 8, so the shift is most certainly going to be wrong. My theory at this point is that the first two solutions are correct (mostly) and I am just missing something...
A bitwise rotation is always necessarily within an integer of a given width. In this case, as you're assuming a 32-bit integer, 2147483662 (0b10000000000000000000000000001110) is indeed the correct answer; you aren't doing anything wrong!
0b11110 would not be considered the correct result by any reasonable definition, as continuing to rotate it right using the same definition would never give you back the original input. (Consider that another right rotation would give 0b1111, and continuing to rotate that would have no effect.)
In my opinion, the spirit of the section of the book which immediately precedes this exercise would have the reader do this problem without knowing anything about the size (in bits) of integers, or any other type. The examples in the section do not require that information; I don't believe the exercises should either.
Regardless of my belief, the book had not yet introduced the sizeof operator by section 2.9, so the only way to figure the size of a type is to count the bits "by hand".
But we don't need to bother with all that. We can do bit rotation in n steps, regardless of how many bits there are in the data type, by rotating one bit at a time.
Using only the parts of the language that are covered by the book up to section 2.9, here's my implementation (with integer parameters, returning an integer, as specified by the exercise): Loop n times, x >> 1 each iteration; if the old low bit of x was 1, set the new high bit.
int rightrot(int x, int n) {
int lowbit;
while (n-- > 0) {
lowbit = x & 1; /* save low bit */
x = (x >> 1) & (~0u >> 1); /* shift right by one, and clear the high bit (in case of sign extension) */
if (lowbit)
x = x | ~(~0u >> 1); /* set the high bit if the low bit was set */
}
return x;
}
You could find the location of the first '1' in the 32-bit value using binary search. Then note the bit in the LSB location, right shift the value by the required number of places, and put the LSB bit in the location of the first '1'.
int bitcount(unsigned x) {
int b;
for(b = 0; x; b++)
x &= x-1;
return b;
}
unsigned rightrot(unsigned x,int n) {
int b = bitcount(x);
unsigned a = (x&~(~0<<n))<<(b-n+1);
x>> = n;
x| = a;
}

Finding trailing 0s in a binary number

How to find number of trailing 0s in a binary number?Based on K&R bitcount example of finding 1s in a binary number i modified it a bit to find the trailing 0s.
int bitcount(unsigned x)
{
int b;
for(b=0;x!=0;x>>=1)
{
if(x&01)
break;
else
b++;
}
I would like to review this method.
Here's a way to compute the count in parallel for better efficiency:
unsigned int v; // 32-bit word input to count zero bits on right
unsigned int c = 32; // c will be the number of zero bits on the right
v &= -signed(v);
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;
On GCC on X86 platform you can use __builtin_ctz(no)
On Microsoft compilers for X86 you can use _BitScanForward
They both emit a bsf instruction
Another approach (I'm surprised it's not mentioned here) would be to build a table of 256 integers, where each element in the array is the lowest 1 bit for that index. Then, for each byte in the integer, you look up in the table.
Something like this (I haven't taken any time to tweak this, this is just to roughly illustrate the idea):
int bitcount(unsigned x)
{
static const unsigned char table[256] = { /* TODO: populate with constants */ };
for (int i=0; i<sizeof(x); ++i, x >>= 8)
{
unsigned char r = table[x & 0xff];
if (r)
return r + i*8; // Found a 1...
}
// All zeroes...
return sizeof(x)*8;
}
The idea with some of the table-driven approaches to a problem like this is that if statements cost you something in terms of branch prediction, so you should aim to reduce them. It also reduces the number of bit shifts. Your approach does an if statement and a shift per bit, and this one does one per byte. (Hopefully the optimizer can unroll the for loop, and not issue a compare/jump for that.) Some of the other answers have even fewer if statements than this, but a table approach is simple and easy to understand. Of course you should be guided by actual measurements to see if any of this matters.
I think your method is working (allthough you might want to use unsigned int). You check the last digit each time, and if it's zero, you discard it an increment the number of trailing zero-bits.
I think for trailing zeroes you don't need a loop.
Consider the following:
What happens with the number (in binary representation, of course) if you subtract 1? Which digits change, which stay the same?
How could you combine the original number and the decremented version such that only bits representing trailing zeroes are left?
If you apply the above steps correctly, you can just find the highest bit set in O(lg n) steps (look here if you're interested in how to do).
Should be:
int bitcount(unsigned char x)
{
int b;
for(b=0; b<7; x>>=1)
{
if(x&1)
break;
else
b++;
}
return b;
}
or even
int bitcount(unsigned char x)
{
int b;
for(b=0; b<7 && !(x&1); x>>=1) b++;
return b;
}
or even (yay!)
int bitcount(unsigned char x)
{
int b;
for(b=0; b<7 && !(x&1); b++) x>>=1;
return b;
}
or ...
Ah, whatever, there are 100500 millions methods of doing this. Use whatever you need or like.
We can easily get it using bit operations, we don't need to go through all the bits. Pseudo code:
int bitcount(unsigned x) {
int xor = x ^ (x-1); // this will have (1 + #trailing 0s) trailing 1s
return log(i & xor); // i & xor will have only one bit 1 and its log should give the exact number of zeroes
}
int countTrailZero(unsigned x) {
if (x == 0) return DEFAULT_VALUE_YOU_NEED;
return log2 (x & -x);
}
Explanation:
x & -x returns the number of right most bit set with 1.
e.g. 6 -> "0000,0110", (6 & -6) -> "0000,0010"
You can deduct this by two complement:
x = "a1b", where b represents all trailing zeros.
then
-x = !(x) + 1 = !(a1b) + 1 = (!a)0(!b) + 1 = (!a)0(1...1) + 1 = (!a)1(0...0) = (!a)1b
so
x & (-x) = (a1b) & (!a)1b = (0...0)1(0...0)
you can get the number of trailing zeros just by doing log2.

Fastest way to count number of bit transitions in an unsigned int

I'm looking for the fastest way of counting the number of bit transitions in an unsigned int.
If the int contains: 0b00000000000000000000000000001010
The number of transitions are: 4
If the int contains: 0b00000000000000000000000000001001
The number of transitions are: 3
Language is C.
int numTransitions(int a)
{
int b = a >> 1; // sign-extending shift properly counts bits at the ends
int c = a ^ b; // xor marks bits that are not the same as their neighbors on the left
return CountBits(c); // count number of set bits in c
}
For an efficient implementation of CountBits see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
Fastest depends on your scenario:
As you specified your datatype as constant sized (unsigned int), it is possible with lookup table. But when you need this operation only once the constant overhead to init the table is too big, and scanning+counting through the int is far faster despite.
I guess the overall best would be a combination: Look up table for a byte or word (256 or 64k entries is not so much), and then combine the bytes/words by their last/first bit.
In C/C++ I would do the following:
unsigned int Transitions(unsigned int value)
{
unsigned int result = 0;
for (unsigned int markers = value ^ (value >> 1); markers; markers = markers >> 1)
{
if (markers & 0x01) result++;
}
return result;
}
Here's the code using arithmetic shift + xor and Kernighan's method for bit counting:
int count_transitions(int x)
{
assert((-1 >> 1) < 0); // check for arithmetic shift
int count = 0;
for(x ^= (x >> 1); x; x &= x - 1)
++count;
return count;
}
What language?
I would loop 64 times and then bit shift your number to inspect of the bits, then store the previous bit and compare it to the current one. If it's different, incremember your count.
Ok, with transitions you mean if you walk through the string of 0-s and 1-s, you count each occurance that a 0 follows a 1 or a 1 follows a 0.
This is easy by shifting bits out and counting the changes:
transitions(n)
result = 0
prev = n mod 2
n = n div 2
while n<>0
if n mod 2 <> prev then
result++
prev = n mod 2
fi
n = n div 2
elihw
return result
you can replace the mod and div with shifts.

Resources