// Converts an integer to a bigint
bigint int_to_bigint(int num){

	if(num==0)
		return init_bigint();
	else{
		int length = 0;
		int tempNum = num;
		while(tempNum!=0){
			tempNum/=10;
			length++;
		}
		if(num<0)
			length++;
		char* value = (char*)malloc((length+1)*sizeof(char));

		value[length] = '\0';//Terminate the string with a NULL character

		if(num<0)
			value[0] = '-';

		int i = length-1;
		tempNum = num>0 ? num:-num;
		
		while(tempNum!=0){

			value[i] = (tempNum%10)+48;
			tempNum/=10;
			i--;

		}
		return make_bigint(value);
	}
}
// Initialize a bigint to zero
bigint init_bigint(){

	char* num = (char*)malloc(2*sizeof(char));
	num[0] = '0';
	num[1] = '\0';
	return make_bigint(num);
	
}
// Multiply a big int with 10^d. 'd' is positive.
bigint shift_by_power_of_10(bigint big_num, int d){

	char* newValue = (char*)malloc((big_num.length+d+1)*sizeof(char));//Terminating with NULL. Hence, the +1 in size.
	
	int i = 0;
	for(i = 0;i<big_num.length;i++){
		newValue[i] = big_num.value[i];
	}
	for(i = big_num.length; i<(big_num.length+d);i++){
		newValue[i] = '0';
	}

	newValue[i] = '\0';//Terminating the string with NULL

	return make_bigint(newValue);
}
int main(int argc, char* argv[]) {
  int n,i;
  scanf("%d",&n);
  bigint num,temp;
  char str[2]="1";
  num=make_bigint(str);
  //printf("%s %d %d\n",num.arr,strlen(num.arr),num.sign);
  //print_bigint(num);
  //printf("\n");
  for(i=1;i<=n;i++){
    temp=int_to_bigint(i);
    num=bigint_mul(num,temp);
    //num.arr[strlen(num.arr)]='\0';
    //print_bigint(num);
  }
  //num.arr[strlen(num.arr)]='\0';
  //printf("%d\n",strlen(num.arr));
  //printf("%s\n",num.arr);
  print_bigint(num);
  return 0;
}
示例#5
0
文件: compile.c 项目: MUME/mudlle
value make_constant(constant c)
{
  struct obj *cst;

  switch (c->vclass)
    {
    case cst_string:
      cst = (value)alloc_string_length(c->u.string.str, c->u.string.len);
      cst->flags |= OBJ_READONLY | OBJ_IMMUTABLE;
      return cst;
    case cst_list: return make_list(c->u.constants);
    case cst_array: return make_array(c->u.constants);
    case cst_int: return makeint(c->u.integer);
    case cst_float: return (value)alloc_mudlle_float(c->u.mudlle_float);
    case cst_bigint: return make_bigint(c->u.bigint_str);
    case cst_table: return make_table(c->u.constants);
    case cst_symbol: return make_symbol(c->u.constpair);
    default:
      abort();
    }
}
//Here, 'a' and 'b' are both positive.
//'a' is greater than 'b'
//Do simple subtraction using borrowing.
//Just do a string subtraction. Pass the string to make_bigint. Return the result obtained from that.
bigint borrow_subtraction(bigint a, bigint b){

	char* result_str = (char*)malloc((a.length+1)*sizeof(char));
	result_str[a.length] = '\0';

	int i = a.length-1, j = b.length-1;
	
	while(i>=0 && j>=0){

		if((a.value[i]-b.value[j])>=0){
			result_str[i] = a.value[i] - b.value[j] + 48;
		}
		
		else{
			result_str[i] = a.value[i] - b.value[j] + 10 + 48;
			
			//Get the borrow from the nearest non-zero number and make the in between numbers as 99..
			int k = i-1;
			while(a.value[k]=='0'){
				a.value[k] = '9';
				k--;
			}
			a.value[k]-=1;
		}

		i--; j--;
	}

	//At this point, 'j' has exhausted. Just copy the rest of the digits to the result_str.
	while(i>=0){
		result_str[i] = a.value[i];
		i--;
	}

	return make_bigint(result_str);
}
int main( int argc, char* argv[] )
{
    char cmd[ BUF_SIZE ];
    // NOTE: Uncomment this once you've implemented this function
       bigint result = init_bigint();
      //bigint result;
    // At the end of every arithmetic operation update the result.

    // In an infinite loop, get input from user
    while( 1 )
    {
        char* op = NULL; // Store the operation
        // Get a line of input from the user
        fgets( cmd, BUF_SIZE, stdin );

        // Parse the line using strtok
        // Note: Given a string like "a b c d", strtok returns "a" the first
        // time it's called, and "b", "c", "d" and NULL subsequently, if the
        // first argument is NULL. Read the manpage for more details
        op = strtok( cmd, " " );
        // If the last line is a new line, make it a null character
        int len = strlen( op );
        if( op[ len-1 ] == '\n' )
          op[ len-1 ] = 0;
        
        // Match the operation, and do appropriate action
        if( strcmp( op, "quit" ) == 0 || op[0] == EOF )
        {
          // Quit when you see this
          break;
        }
        else if( strcmp( op, "set" ) == 0 )
        {
          // set <data>
          // Sets a big int value to data
         
          int data;
          if( read_args1( &data ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
           // printf( "Setting value as %d\n", data );
            // NOTE: Uncomment this once you've implemented this function
             result = int_to_bigint(data);
          }
        }
        
        else if( strcmp( op, "add" ) == 0 )
        {
          // add <num1> <num2> 
          // Adds two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Add %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_add( a, b);
             print_bigint(result);
          }
        }
        
        else if( strcmp( op, "sub" ) == 0 )
        {
          // sub <num1> <num2> 
          // Subtracts two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Subtract %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_sub( a, b);
             print_bigint(result);
	     printf("\n");
          }
        }
        
        else if( strcmp( op, "mul" ) == 0 )
        {
          // mul <num1> <num2> 
          // Multiplies two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Multiply %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_mul( a, b);
             print_bigint(result);
          }
        }
        else if( strcmp( op, "div" ) == 0 )
        {
          // add <num1> <num2> 
          // Adds two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Divide %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_div( a, b);
             print_bigint(result);
          }
        }
        else
        {
          printf( "Invalid command\n" );
        }

    }

    return 0;
}
 string multiply(string num1, string num2) {
     return to_string(make_bigint(num1) * make_bigint(num2));
 }
//TODO: Define the division for negative numbers. Define it simply as the truncation of the fractional part.
// Divides two bigints and returns a bigint similar to 9/4 = 2
// Long division method.
bigint bigint_div(bigint a, bigint b){

	if(compare_bigint(b, make_bigint("0"))==0){
		printf("Divide by ZERO error.\n");
		return make_bigint("0");
	}

	//Take care of the sign first
	int positivity = ((a.pos==1&&b.pos==1)||(a.pos==0&&b.pos==0))?1:0;
	a.pos = 1; b.pos = 1;

	//Now check if we really need to divide in the first place.
	int max_flag = compare_bigint(a,b);

	if(max_flag<0)
		return init_bigint();//No need to divide as the dividend is lesser in magnitude than the divisor.
	
	else if(max_flag==0){
		bigint tempBigInt = make_bigint("1");
		tempBigInt.pos = positivity;
		return tempBigInt;
	}

	else{

		char toAppend[2];
		toAppend[1] = '\0';

		//Quotient stores the final answer we need to return. For every character seen in the dividend, a number
		//gets added to the quotient.
		char* quotient = (char*)malloc((a.length+1)*sizeof(char));
		quotient[0] = '\0';

		//The current dividend can be at most the divisor's length +1. The extra +1 is for '\0'.
		char* current_dividend_str = (char*)malloc((b.length+1+1)*sizeof(char));
		current_dividend_str[0] = '\0';
		//Long division

		int dividend_index = 0;//This stores the current dividend index and acts as the iterator in the long division method

		//Take character by character from the dividend and perform long division
		while(dividend_index<a.length){
	
			toAppend[0] = a.value[dividend_index];
			strcat(current_dividend_str, toAppend);
			bigint current_dividend_bigint = make_bigint(current_dividend_str);

			int compare_division_state = compare_bigint(current_dividend_bigint, b);
			if(compare_division_state==-1){
				quotient[dividend_index] = '0';
			}
			else{

				//remainder is indeed positive. So the 'pos' field is redundant. So, we use the 'pos' field to store the quotient.
				//The value field stores the remainder. Length stores the length of the remainder.
				//The quotient will only be a single digit.
				bigint remainder = get_remainder_quotient(current_dividend_bigint, b);
				quotient[dividend_index] = remainder.pos+48;// 'pos' stores the remainder. 48 is the ASCII value of 0.
				strcpy(current_dividend_str,remainder.value);

			}
			dividend_index++;
		}
		bigint tempBigInt = make_bigint(quotient);
		tempBigInt.pos = positivity;
		return tempBigInt;
	}
}
// Parse a string to make it a Big Integer
bigint make_bigint(char* str){

	if(!valid(str)){
		bigint flag_bigInt = make_bigint("-1");//'-1' is useful to indicate an invalid string for factorial
		flag_bigInt.length = -1;//A negative length is like a flag indicating an invalid string
		//So, flag_bigint flags invalid strings for both, main and factorial at the same time.
		return flag_bigInt;
	}

	//Assume that a valid string has been entered at this point
	
	bigint number;
	if(str[0]=='-')
		number.pos = 0;
	else
		number.pos = 1;//The first digit can be '+' also. Take care of that.

	//Find the length of the string first. Allocate the memory to the new string. Then fill the string.

	int length = 0;//Stores the meaningful length without the trailing zeros
	int trailingZeros = 0;//counts the number of trailing zeros

	char* tempStr = str;
	if(number.pos==0)
		tempStr++;//Start the string from the digits after skipping the negative sign '-'

	int flag = 0;//This flag is used to check the trailing zeros in the beginning of a number

	//Find length
	while(*tempStr!='\0'){
		if(flag==0 && *tempStr=='0')
			trailingZeros++;
		
		else if(*tempStr!='0' && flag==0){
			flag = 1;
			length++;
		}
		else
			length++;
		
		tempStr++;
	}

	if(length==0)//all were zeros
	{
		number.length = 1;
		number.value = (char*)malloc(2*sizeof(char));
		number.value[0] = '0';
		number.value[1] = '\0';
		return number;
	}

	//If the number was not zero, come here
	number.length = length;
	//Allocate memory dynamically
	number.value = (char*)malloc((length+1)*sizeof(char));//+1 for an extra null character at the end
	tempStr = str;
	if(number.pos==0)
		tempStr++;//Start the string from the digits after skipping the negative sign '-'


	int index=0;
	//Fill in the string for value
	while(index<length){
		number.value[index] = tempStr[index+trailingZeros];
		index++;
	}
	number.value[index] = '\0';
	return number;
}
// Adds two bigints and returns the result which is a bigint
bigint bigint_add(bigint a, bigint b){

	//If they are of the opposite signs, then send them for subtraction
	if(a.pos==0&&b.pos==1||a.pos==1&&b.pos==0){

		if(a.pos==0){
			a.pos = 1;//Make it positive and send it for subtraction.
			return bigint_sub(b,a);//Returns (b-a)
		}

		else{
			b.pos = 1;//Make it positive and send it for subtraction.
			return bigint_sub(a,b);//Returns (a-b)
		}
	}
	//If of the same sign, then add.
	else{
		bigint bigger_num, smaller_num;// Here the bigger number is in terms of the absolute quantity.

		if(!a.pos){
			if(compare_bigint(a,b)==1){
				bigger_num = b; smaller_num = a;
			}
			else if(compare_bigint(a,b)==-1){
				bigger_num = a; smaller_num = b;
			}
			else{
				//Both are equal. Assign any number to any variable.
				bigger_num = a; smaller_num = b;
			}
		}
		else{
			if(compare_bigint(a,b)==1){
				bigger_num = a; smaller_num = b;
			}
			else if(compare_bigint(a,b)==-1){
				bigger_num = b; smaller_num = a;
			}
			else{
				//Both are equal. Assign any number to any variable.
				bigger_num = b; smaller_num = a;
			}
		}

		//At this point, bigger_num has the larger number in absolute terms. The 'smaller_num' contains the other.
		//Now, create a new character array which can hold the sum of the two terms and pass that array to make_bigint
		//For the new character array, assign memory 1 greater than the length of the bigger_num.
		//In case the left hand most field doesn't get filled up, then assign 0 to it. make_bigint takes care of that.

		int new_length = bigger_num.length+1;//This length excludes the negative sign.
		char* new_value;
		if(bigger_num.pos==0){
		 	new_value = (char*)malloc((new_length+1+1)*sizeof(char));//+1 for the negative sign and +1 for terminating it with NULL
			new_value[0] = '-';
			new_value[new_length+1] = '\0';//Terminating with a null character
		}
		else{
		 	new_value = (char*)malloc((new_length+1)*sizeof(char));//+1 for terminating it with null.
			new_value[new_length] = '\0';//Terminating with a null character
		}

		addValues(bigger_num, smaller_num, new_value, new_length);//Does string addition and stores the result in new_value
 		return make_bigint(new_value);
	}//Else ends
}