Table of Contents

Project: BIG NUM

A project for C++ by Robert Matsch during the spring 2012.

This project was begun on 3/12/2012 and is anticipated to take 5 days to complete. Project was completed on 3/20, 2012.

Objectives

Create a program that can take two numbers from user that are up to 24 didgits in lenth and allow user to choose from options such as to multiply,divide,subtract,or add the two numbers.

Prerequisites

In order to successfully accomplish/perform this project, the listed resources/experiences need to be consulted/achieved:

Scope

This project will have you implementing code to support the storage and manipulation of numbers outside of the established data types.

In C, from our first project (Project #0), we explored the various established data types, and determined their various sizes and representational ranges.

From that, we should know the largest value we can store in a variable using the biggest data type size (unsigned long long int), which is: 18,446,744,073,709,551,615

That's a 20-digit number.

But this project will have us creating the ability to store and manipulate largers much larger than that. We'll start with a target of 4 and 24 digits (if you write your code effectively, the number of digits should ultimately not matter).

Why 4? Can't we already easily store values of 4 digits?

Yes, but looking to implement the ability to store and manipulate a 4 digit number will help us to better realize the logic and code necessary to scale our solution to support any number of digits.

While there are many approaches to this problem, follow through this example to get some insight. You don't have to take this approach, but it will cover some important concepts you will need to implement in your solution, whether or not you take this approach.

Let's look at a 4 digit number not as a side-effect of being able to be stored in a quantity of appropriate size, but as 4 literal stored digits in memory. To wit:

    unsigned char *value;
    value = (unsigned char *) malloc (sizeof(unsigned char) * 4);
    *(value+0) = *(value+1) = *(value+2) = *(value+3) = 0;

What just happened here? Make sure you understand, or ask questions and get clarification before attempting to continue.

Essentially, we have just allocated 4 bytes of memory (of type unsigned char), which are located consecutively in memory. To draw a picture, we'd have this:

0 0 0 0
*(value+0) *(value+1) *(value+2) *(value+3)

4 bytes of memory, each containing a single digit of our 4 digit number. Let's assume we are attacking this as a decimal (base 10) value, and we'll maintain our assumption that the left-most value is the most significant digit, and the right-most value is the least significant digit.

For example, let's say we wanted to store the 4-digit number 8192 in memory using this scheme. The code and resulting “picture” would be as follows:

    *(value+0) = 8;
    *(value+1) = 1;
    *(value+2) = 9;
    *(value+3) = 2;
8 1 9 2
*(value+0) *(value+1) *(value+2) *(value+3)

Make sense?

Be aware that *(value+0), the first memory address of our sequence, is at the left side of our value… therefore it stores the most significant digit. You are free to do it the other way, just make sure that whatever approach you take, you maintain your logic.

Now, what if we wanted to perform an addition?

8192+4 = 8196

Pretty easy right?

4 in our memory scheme would be represented as “0004”, and we'd accomplish the addition as follows:

    *(value+0) = *(value+0) + 0;
    *(value+1) = *(value+1) + 0;
    *(value+2) = *(value+2) + 0;
    *(value+3) = *(value+3) + 4;

As you can see, the value of “4” was added only to the last (least significant) digit stored in our value. Displaying it should should the expected answer:

8 1 9 6
*(value+0) *(value+1) *(value+2) *(value+3)

There's actually two situations that occur with adding… what we just saw was the straight “sum”. In this case, the sum was the only meaningful result generated.

But there's also another situation we can have, and that is a carry. A carry is when the result is too big to be stored in a single digit (ie a 2 digit number). So we react by storing the least significant digit and carrying the most significant digit to the next placevalue.

Let's take our 8196 and add 1024 to it. What do we get? 9220

Illustrated, we have:

Carry: 0 1 1 0
Value: 8 1 9 6
Addend: 1 0 2 4
Sum: 9 2 2 0
*(value+0) *(value+1) *(value+2) *(value+3)

So, for this project I'd like for you to write a set of functions and a test program that:

Code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void sum(unsigned char *n1,unsigned char *n2, unsigned char *n3);
void subtraction(unsigned char *n1, unsigned char *n2, unsigned char *n3);
void multiply(unsigned char *n1, unsigned char *n2, unsigned char *n3);
void divide(unsigned char *n1, unsigned char *n2, unsigned char *n3);
int compare(unsigned char *n2, unsigned char *zero);

int compare(unsigned char *n2,unsigned char *zero)
{
        int a;
        unsigned char flag;
        flag=0;
        for (a=23; a>=0; a--){
                if (*(n2+a)==*(zero+a)){
                        flag=0;
                }else{
                        flag=1;
                        break;
                }
        }
        return(flag);
}
void sum(unsigned char *n1,unsigned char *n2, unsigned char *n3)
{
        int a, z, i, x;
        for (a= 23; a>=0; a--){
                *(n3+a) = 0;
        }
        for(a=23; a >= 0; a--){
                z = *(n3+a) + (*(n1+a)+ *(n2+a));
                if (z>9){
                        i = z-10;
                        n3[a] = i;
                        n3[a-1] = n3[a-1]+1;
                }if (z<9){
                        n3[a]=z;
                }
        }
}
void subtraction(unsigned char *n1,unsigned char *n2,unsigned char *n3)
{
        int a, z, i, x;
        for (a= 23; a>=0; a--){
                *(n3+a) = 0;
        }
        for(a=23; a>=0; a--){
                z = *(n3+a) + (*(n1+a) - *(n2+a));
                if (z>=0){
                        n3[a]=z;
                }else{
                        n3[a-1]=n3[a-1]-1;
                        n3[a]=z+10;

                }
        }
}

void multiply(unsigned char *n1,unsigned char *n2, unsigned char *n3)
{
        unsigned char *zero, *one, *num1value, *copyn1,*num1value2,*copyn2;
        int a, z, i, x;

        copyn2=(unsigned char *)malloc(sizeof(unsigned char)*24);
        copyn1=(unsigned char *)malloc(sizeof(unsigned char)*24);
        zero=(unsigned char *)malloc(sizeof(unsigned char)*24);
        one=(unsigned char *)malloc(sizeof(unsigned char)*24);
        num1value=(unsigned char *)malloc(sizeof(unsigned char)*24);
        num1value2=(unsigned char *)malloc(sizeof(unsigned char)*24);
        for (a=23; a>=0; a--){
                *(num1value+a) = *(n1+a);
                *(num1value2+a)=*(n1+a);
                *(zero+a)=0;
                *(n1+a)=0;
                *(one+a)= 0;
                *(copyn1+a)=*(n1+a);
                *(copyn2+a)=*(n2+a);
        }
        *(one+23)= 1;
        while (compare(n2,zero) != 0){
                sum(n1,num1value,n3);
                for (a=23; a>=0; a--){
                        *(n1+a)=*(n3+a);
                        *(n3+a)=0;
                }
                subtraction(n2,n1,n3);
                for (a=23; a>=0; a--){
                        *(n2+a)=*(n3+a);
                        *(n3+a)=0;
                }
        }
        for (a=23; a>=0; a--){
                *(n3+a)=*(n1+a);
                *(n1+a)=*(num1value2+a);
                *(n2+a)=*(copyn2+a);
        }
}
void divide(unsigned char *n1,unsigned char *n2, unsigned char *n3)
{

         unsigned char *zero, *one, *num1value,*copyn2,*copyn1,*num1value2;
        int a, z, i, x;
        copyn2=(unsigned char *)malloc(sizeof(unsigned char)*24);
        copyn1=(unsigned char *)malloc(sizeof(unsigned char)*24);
        num1value2=(unsigned char *)malloc(sizeof(unsigned char)*24);
        zero=(unsigned char *)malloc(sizeof(unsigned char)*24);
        one=(unsigned char *)malloc(sizeof(unsigned char)*24);
        num1value=(unsigned char *)malloc(sizeof(unsigned char)*24);
        for (a=23; a>=0; a--){
                *(num1value+a) = *(n1+a);
                *(zero+a)=0;
                *(n1+a)=0;
                *(one+a)= 0;
                *(num1value2+a)=*(n1+a);
                *(copyn1+a)=*(n1+a);
                *(copyn2+a)=*(n2+a);


        }
        *(one+23)= 1;
        while (compare(num1value,zero) != 0){
              sum(n1,num1value,n3);
             for (a=23; a>=0; a--){
                        *(n1+a)=*(n3+a);
                        *(n3+a)=0;
                }
                subtraction(n2,n1,n3);
                for (a=23; a>=0; a--){
                        *(n2+a)=*(n3+a);
                        *(n3+a)=0;
                }
        } for (a=23; a>=0; a--){
                *(n3+a)=*(n1+a);
                *(n1+a)=*(num1value2+a);
                *(n2+a)=*(copyn2+a);
        }
}
int main() {
        unsigned char i, x,counter, operation, *n1, *n2, *n3, z, a, y,choice;
        n1=(unsigned char *)malloc(sizeof(unsigned char)*24);
        n2=(unsigned char *)malloc(sizeof(unsigned char)*24);
        n3=(unsigned char *)malloc(sizeof(unsigned char)*24);
        printf("please enter a number up to 24 digits long padded with zeros:\n");
        printf("example: 000000000000000000000008 = 8\n");
        x = fgetc(stdin);
        counter=0;
        while(x != '\n'){
                x = x - 48;
                *(n1+counter)= x;
                x = fgetc(stdin);
                counter++;
        }printf("please enter another number up to 24 digits long padded with zeros:\n");
        y = fgetc(stdin);
        counter=0;
        while(y != '\n'){
                y=y-48;
                *(n2+counter)= y;
                y = fgetc(stdin);
                counter++;
        }printf("Addition, subtraction, multiplying, Dividing\n");
        printf("Enter 0 for Addition, 1 for Subtractiom, 2 for Multiplying, and 3 for Division or 5 for exit :\n");
        choice=0;
        operation = fgetc(stdin);
        choice = operation-48;
        while  (3 >= choice >= 0){
                if (choice ==0){
                        sum(n1,n2,n3);
                        for(a=0;a<24;a++){
                                printf("%c",n3[a]+48);
                        }
                }if (choice ==1){
 subtraction(n1,n2,n3);
                        for(a=0;a<24;a++){
                                printf("%c",n3[a]+48);
                        }
                }if (choice ==2){
                        multiply(n1,n2,n3);
                        for(a=0;a<24;a++){
                                printf("%c",n3[a]+48);
                        }
                }if (choice ==3){
                        divide(n1,n2,n3);
                        for(a=0;a<24;a++){
                                printf("%c",n3[a]+48);
                        }
                }if (choice ==5){
                        exit(1);
                }
                printf("\nif you would like to perform other operations: 0 for addition, 1 for subtraction, 2 for multiply, 3 for division,and 5 to exit program:\n");
                choice=0;
                operation = fgetc(stdin);
                operation = fgetc(stdin);
                choice = operation-48;
  }


        return(0);
}

Execution

lab46:~/src/cprog/project2$ ./prog2f
please enter a number up to 24 digits long padded with zeros:
example: 000000000000000000000008 = 8
000000000000000000000015
please enter another number up to 24 digits long padded with zeros:
000000000000000000000003
Addition, subtraction, multiplying, Dividing
Enter 0 for Addition, 1 for Subtraction, 2 for Multiplying, and 3 for Division or 5 for exit :
0
000000000000000000000018
if you would like to perform other operations: 0 for addition, 1 for subtraction, 2 for multiply, 3 for division,and 5 to exit program:
1
000000000000000000000012
if you would like to perform other operations: 0 for addition, 1 for subtraction, 2 for multiply, 3 for division,and 5 to exit program:
2
000000000000000000000045
if you would like to perform other operations: 0 for addition, 1 for subtraction, 2 for multiply, 3 for division,and 5 to exit program:
3
000000000000000000000005
if you would like to perform other operations: 0 for addition, 1 for subtraction, 2 for multiply, 3 for division,and 5 to exit program:
5
lab46:~/src/cprog/project2$

Reflection

upon completion of this project i learned how to use arrays to collect large user input and manipulate the input through simple repeated addition and subtraction.

References

In performing this project, the following resources were referenced:

C++ class notes