I was making a binary adder in C using only logic gates. Now for example, I wanted to add 4 + (-5)
so I would get the answer in 2's complement and then convert it to decimal. In the same way, if I do, 4 + (-3)
I would get the answer in binary and would like to use the same function to convert it to decimal.
Now, I know how to convert a 2's complement number into decimal, convert binary into decimal. But I want to use the same function to convert both 2's complement and binary into decimal. To do that, I have to figure out if the number is binary or 2's complement. It is where I am stuck.
Can someone give me an idea, algorithm or code in C to find out whether a number is 2's complement or normal binary?
SOURCE CODE
Chips
// Author: Ashish Ahuja
// Date created: 8-1-2016
// Descriptions: This file stores all the chips for
// the nand2tetris project.
// Links: www.nand2tetris.org
// class.coursera.org/nand2tetris1-001
// Files needed to compile successfully: ourhdr.h
int not (unsigned int a) {
if (a == 1) {
return 0;
}
else if (a == 0) {
return 1;
}
}
int and (unsigned int a, unsigned int b) {
if (a == 1 && b == 1)
return 1;
else if ((a == 1 && b == 0) || (a == 0 && b == 1) || (a == 0 && b == 0))
return 0;
}
int nand (unsigned int a, unsigned int b) {
unsigned int ans = 10;
ans = and (a, b);
unsigned int ack = not (ans);
return ack;
}
int or (unsigned int a, unsigned int b) {
return (nand (not (a), not (b)));
}
int nor (unsigned int a, unsigned int b) {
return (not (or (a, b)));
}
int xor (unsigned int a, unsigned int b) {
unsigned int a_r;
unsigned int b_r;
unsigned int sra;
unsigned int srb;
a_r = not (a);
b_r = not (b);
sra = nand (a_r, b);
srb = nand (b_r, a);
return nand (sra, srb);
}
int xnor (unsigned int a, unsigned int b) {
return (not (xor (a,b)));
}
Ourhdr.h
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include <termios.h>
#include <stddef.h>
#include <sys/types.h>
#include <my/signal.h>
#include <my/socket.h>
#include <my/io.h>
#include <my/lib.h>
#include <my/tree.h>
#include <my/bits.h>
#include <my/binary.h>
//#include <my/error.h>
#define MAXLINE 4096
#define BUFF_SIZE 1024
Note: I am gonna only show headers needed by this project. So just think that the other headers are of no use.
Function to Convert array to integer
int array_num (int arr [], int n) {
char str [6] [2];
int i;
char number [13] = {'\n'};
for (i = 0; i < n; i ++)
sprintf (str [i], "%d", arr [i]);
for (i = 0; i < n; i ++)
strcat (number, str [i]);
i = atoi (number);
return i;
}
Function to get bits of an int, and return an pointer to an array containing bits
int *get_bits (int n, int bitswanted) {
int *bits = malloc (sizeof (int) * bitswanted);
int k;
int mask;
int masked_n;
int thebit;
for (k = 0; k < bitswanted; k ++) {
mask = 1 << k;
masked_n = n & mask;
thebit = masked_n >> k;
bits [k] = thebit;
}
return bits;
}
Function to convert binary to decimal, and vice-versa
int convert_num (int n, int what) {
int rem;
int i;
int binary = 0;
int decimal = 0;
switch (what) {
case 0: // Convert decimal to binary
i = 0;
rem = 0;
while (n != 0) {
rem = n % 2;
n /= 2;
binary += rem * i;
i *= 10;
}
return binary;
break;
case 1: // Convert binary to decimal
i = 0;
rem = 0;
while (n != 0) {
rem = n % 10;
n /= 10;
decimal += rem*pow (2, i);
i ++;
}
return decimal;
break;
}
}
Main program design
n1
and n2
from userbits1
and bits2
which point to an array which have the bits of n1
and n2
. Note, that the array will be in reverse order, i.e, the last bit will be in the 0th
variable of the array.1
and 0
, and carry is 1
, so, the return will be 0
and carry will be again changed to 1
.sum
.sum
will be converted to an int using the function I have given above.NOTE: The nand2tetris
project is done in hdl
but I was familiar to do it with C. Also, many of the function I have mentioned above have been taken from stackoverflow
. Although, the design is my own.
Fun fact about 2s complement - and reason it has become so widely used is:
For addition you don't need to know if it is negative or positive. Just add as unsigned.
Subtraction is similar, but you have to negate the second operand (see below).
The only thing you might have to care about is overflow. For that you have to check if the sign of the result can actually result from the signs of the two inputs and a addition-overflow from the pre-most to the most signigficant bit.
Negation of int n
is simply done by 0 - n
. Alternatively, you can invert all bits and add 1
- that's what a CPU or hardware subtracter basically does.
Note that 2's complement binaries have an asymmetric range: -(N+1) ... N
.
For conversion, just check for the minimum value (must be treated seperately) and output directly, otherwise get the sign (if ( n < 0 )
) and negate the value (n = -n
) and finally convert the -then unsigned/positive - value to a string or character stream.