//======================================================================
// File name:	mult16s.c
// File type:   GNU C++ language source code file.
//
// Description:
//	This file defines a function called mult16s() that performs
//	multiplication of 16-bit two's complement numbers (represented
//	in sign-extended form in 32-bit registers).  The file
//	also contains an auxilliary output routine for debugging 
//	purposes, and a main() routine that exercises mult16s() by
//	performing some multiplications and printing the results.
//
// Author:	Michael P. Frank
// Created:	March 21, 2006
//======================================================================

#include <stdio.h>

//----------------------------------------------------------------------
// Function name:	mult16s()
// Description:
//	Algorithm to carry out multiplication of signed 16-bit numbers
//	(encoded in sign-extended form in 32-bit ints) using shift and
//	add/subtract operations.
// Arguments:
//	int mand - 16-bit signed multiplicand, sign-extended to 32 bits
//	int mer	 - 16-bit signed multiplier, sign-extended to 32 bits
//----------------------------------------------------------------------
int mult16s(int mand, int mer){
	unsigned i;			// loop index variable
	int prod = 0;			// initialize product to 0
	for (i=0; i<15; i++)	  	// at each positive position,
		if (mer&(1<<i)) 	  	//   if bit is a 1,
			prod += mand<<i;	//     add mand*(2^i);
	if (mer&(1<<15)) 		// if sign bit is 1,
		prod -= mand<<15;	//   subtract multiplcand*(2^15)
	return prod;			// return result
}		  	

//---------------------------------------------------------------------
// Function name:	verbose_mult16s()
// Description:
//	Calls mult16s() to multiply mand by mer, while printing the
//	inputs and outputs to stdout in a friendly ASCII message.
// Arguments:
//	int mand - 16-bit signed multiplicand, sign-extended to 32 bits
//	int mer	 - 16-bit signed multiplier, sign-extended to 32 bits
//---------------------------------------------------------------------
void verbose_mult16s(int mand, int mer){
	int result;
	printf("When %d is multiplied by %d the product is...\n",mand,mer);
	result = mult16s(mand,mer);
	printf("\t%d.\n",result);
}

//----------------------------------------------------------------------
// main() routine: Exercise the mult16s routine and print the results.
//----------------------------------------------------------------------
int main(int argc, char**argv){
	// Try some multiplications of various sizes and sign combinations.
	// For correct results, all arguments here must fit in a signed 
	// 16-bit two's complement integer.  (Range: -32768 to +32767.)
	verbose_mult16s(12,7);
	verbose_mult16s(-4,3);
	verbose_mult16s(6,-5);
	verbose_mult16s(32041,31507);
	verbose_mult16s(32767,-32768);
	verbose_mult16s(-31402,-29859);
}

