/** Test Function */ int main( ) { bignum n1, n2, n3, zero; // Instantiate string buffers for big numbers a and b char* a = calloc( MAXDIGITS, sizeof( char ) ); char* b = calloc( MAXDIGITS, sizeof( char ) ); // Get big numbers a and b as strings printf( "a = " ); fgets( a, MAXDIGITS, stdin ); printf( "b = " ); fgets( b, MAXDIGITS, stdin ); // Remove the newline character (if present) from string buffers char* nl; if( ( nl = strchr( a, '\n' ) ) != NULL ) *nl = '\0'; if( ( nl = strchr( b, '\n' ) ) != NULL ) *nl = '\0'; // Create a and b big number instances via the string buffers string_to_bignum( a, &n1 ); string_to_bignum( b, &n2 ); // Test addition add_bignum( &n1, &n2, &n3 ); printf( "a + b = " ); print_bignum( &n3 ); // Test comparison int comparison = compare_bignum( &n1, &n2 ); printf( "a %s b\n", comparison == 0 ? "==" : ( comparison < 0 ? ">" : "<" ) ); // Test subtraction subtract_bignum( &n1, &n2, &n3 ); printf( "a - b = " ); print_bignum( &n3 ); // Test multiplication multiply_bignum( &n1, &n2, &n3 ); printf( "a * b = " ); print_bignum( &n3 ); // Test division int_to_bignum( 0, &zero ); if( compare_bignum( &zero, &n2 ) == 0 ) { printf( "a / b = NaN\n" ); } else { divide_bignum( &n1, &n2, &n3 ); printf( "a / b = " ); print_bignum( &n3 ); } return 0; }
void divide_bignum(bignum *a, bignum *b, bignum *c) { bignum row, tmp; int asign, bsign, i, j; initialize_bignum(c); c->signbit = a->signbit * b->signbit; asign = a->signbit; bsign = b->signbit; a->signbit = PLUS; b->signbit = PLUS; initialize_bignum(&row); initialize_bignum(&tmp); c->lastdigit = a->lastdigit; for (i = a->lastdigit; i >= 0; i--) { digit_shift(&row, 1); row.digits[0] = a->digits[i]; c->digits[i] = 0; while (compare_bignum(&row, b) != PLUS) { c->digits[i]++; subtract_bignum(&row, b, &tmp); row = tmp; } } zero_justify(c); a->signbit = asign; b->signbit = bsign; }
void subtract_bignum(bignum *a, bignum *b, bignum *c) { int borrow, v, i; if ((a->signbit == MINUS) || (b->signbit == MINUS)) { b->signbit = -1 * b->signbit; add_bignum(a, b, c); b->signbit = -1 * b->signbit; return; } if (compare_bignum(a, b) == PLUS) { subtract_bignum(b, a, c); c->signbit = MINUS; return; } c->lastdigit = max(a->lastdigit, b->lastdigit); borrow = 0; for (i = 0; i <= c->lastdigit; i++) { v = (a->digits[i] - borrow - b->digits[i]); if (a->digits[i] > 0) borrow = 0; if (v < 0) { v = v + 10; borrow = 1; } c->digits[i] = (char) v % 10; } zero_justify(c); }
int main(void) { int a,b; bignum n1,n2,n3,zero; while (scanf("%d %d",&a,&b) != EOF) { printf("a = %d b = %d\n",a,b); int_to_bignum(a,&n1); int_to_bignum(b,&n2); add_bignum(&n1,&n2,&n3); printf("addition -- "); print_bignum(&n3); printf("compare_bignum a ? b = %d\n",compare_bignum(&n1, &n2)); subtract_bignum(&n1,&n2,&n3); printf("subtraction -- "); print_bignum(&n3); multiply_bignum(&n1,&n2,&n3); printf("multiplication -- "); print_bignum(&n3); int_to_bignum(0,&zero); if(compare_bignum(&zero, &n2) == 0) printf("division -- NaN \n"); else { divide_bignum(&n1,&n2,&n3); printf("division -- "); print_bignum(&n3); } printf("--------------------------\n"); } return 0; }
/** Subtracts big numbers; i.e. c = a - b */ void subtract_bignum( bignum* a, bignum* b, bignum* c ) { int borrow; /* has anything been borrowed? */ int v; /* placeholder digit */ int i; /* counter */ initialize_bignum( c ); if( ( a->signbit == MINUS ) || ( b->signbit == MINUS ) ) { b->signbit = -1 * b->signbit; add_bignum( a, b, c ); b->signbit = -1 * b->signbit; return; } if( compare_bignum( a, b ) == PLUS ) { subtract_bignum( b, a, c ); c->signbit = MINUS; return; } c->lastdigit = max( a->lastdigit, b->lastdigit ); borrow = 0; for( i = 0; i <= ( c->lastdigit ); i++ ) { v = ( a->digits[ i ] - borrow - b->digits[ i ] ); if( a->digits[ i ] > 0) { borrow = 0; } if( v < 0 ) { v = v + 10; borrow = 1; } c->digits[ i ] = ( char ) v % 10; } zero_justify( c ); }
void divide_bignum(bignum *a, bignum *b, bignum *c) { bignum row; /* represent shifted row */ bignum tmp; /* placeholder bignum */ int asign, bsign; /* temporary signs */ int i; /* counters */ initialize_bignum(c); c->signbit = a->signbit * b->signbit; asign = a->signbit; bsign = b->signbit; a->signbit = PLUS; b->signbit = PLUS; initialize_bignum(&row); initialize_bignum(&tmp); c->lastdigit = a->lastdigit; for(i = a->lastdigit; i >= 0; i--) { digit_shift(&row,1); row.digits[0] = a->digits[i]; c->digits[i] = 0; while(compare_bignum(&row,b) != PLUS) { c->digits[i] ++; subtract_bignum(&row,b,&tmp); row = tmp; } } zero_justify(c); a->signbit = asign; b->signbit = bsign; }