Friday, March 15, 2013

Utility function for generating required number digits after decimal point.


//
#include <stdio.h>
#include <string.h>
//

/**
-------------------------------------------------------------------
Problem :
-------------------------------------------------------------------
For a given fraction [x / y] finding "n" number of digits after the 
decimal point. 

"x" and "y" are positive integers

The value after the decimal will not be rounded but will be 
truncated to "n" digits
-------------------------------------------------------------------
 
-------------------------------------------------------------------
Example :
-------------------------------------------------------------------
[1]
x = 22
y = 7
x / y = 3.1428571428571428571428571428571...
Required DigitsAfterDecimalPoint = 20
BufferPrecision = "14285714285714285714"
 
[2]
x = 7
y = 22
x / y = 0.3181818181818181818181818181818...
Required DigitsAfterDecimalPoint = 20
BufferPrecision = "31818181818181818181"

[3]
x = 7
y = 7
x / y = 1.00000000000000000000000000000000...
Required DigitsAfterDecimalPoint = 20
BufferPrecision = "00000000000000000000"
-------------------------------------------------------------------

-------------------------------------------------------------------
Function Description :
-------------------------------------------------------------------
void GetRequiredPrecision(int _x, int _y, int _iDigitsAfterDecimalPoint, char *_pcBufferPrecision);
[in]_x : Dividend
[in]_y : Divisor
[in]_iDigitsAfterDecimalPoint : The number of digits which are required after the decimal point
[out]_pcBufferPrecision : Pointer to buffer which will hold the result.
_pcBufferPrecision should point to a buffer of length (_iDigitsAfterDecimalPoint + 1)
-------------------------------------------------------------------
/**/
void GetRequiredPrecision(int _x, int _y, int _iDigitsAfterDecimalPoint, char *_pcBufferPrecision)
{
 if((_x % _y) == 0)
 {
  memset(_pcBufferPrecision, '0', _iDigitsAfterDecimalPoint);
  _pcBufferPrecision[_iDigitsAfterDecimalPoint] = 0;
  return;
 }

 int table[11];
 table[0] = _y * 0;
 table[1] = _y * 1;
 table[2] = _y * 2;
 table[3] = _y * 3;
 table[4] = _y * 4;
 table[5] = _y * 5;
 table[6] = _y * 6;
 table[7] = _y * 7;
 table[8] = _y * 8;
 table[9] = _y * 9;
 table[10] = _y * 10;

 int iCount = 0;
 int iReminder = _x % _y;  
 int iNewReminder = 0;

 while(_iDigitsAfterDecimalPoint-- > 0)
 {
  iNewReminder = (iReminder << 3) + (iReminder << 1);

  if((iNewReminder >= table[0]) && (iNewReminder <= (table[1]-1)))
  {
   _pcBufferPrecision[iCount] = '0';
   iReminder = iNewReminder;
  }   
  else if((iNewReminder >= table[1]) && (iNewReminder <= (table[2]-1)))
  {
   _pcBufferPrecision[iCount] = '1';
   iReminder = iNewReminder - table[1];
  }
  else if((iNewReminder >= table[2]) && (iNewReminder <= (table[3]-1)))
  {
   _pcBufferPrecision[iCount] = '2';
   iReminder = iNewReminder - table[2];
  }
  else if((iNewReminder >= table[3]) && (iNewReminder <= (table[4]-1)))
  {
   _pcBufferPrecision[iCount] = '3';
   iReminder = iNewReminder - table[3];
  }
  else if((iNewReminder >= table[4]) && (iNewReminder <= (table[5]-1)))
  {
   _pcBufferPrecision[iCount] = '4';
   iReminder = iNewReminder - table[4];
  }
  else if((iNewReminder >= table[5]) && (iNewReminder <= (table[6]-1)))
  {
   _pcBufferPrecision[iCount] = '5';
   iReminder = iNewReminder - table[5];
  }
  else if((iNewReminder >= table[6]) && (iNewReminder <= (table[7]-1)))
  {
   _pcBufferPrecision[iCount] = '6';
   iReminder = iNewReminder - table[6];
  }
  else if((iNewReminder >= table[7]) && (iNewReminder <= (table[8]-1)))
  {
   _pcBufferPrecision[iCount] = '7';
   iReminder = iNewReminder - table[7];
  }
  else if((iNewReminder >= table[8]) && (iNewReminder <= (table[9]-1)))
  {
   _pcBufferPrecision[iCount] = '8';
   iReminder = iNewReminder - table[8];
  }
  else if((iNewReminder >= table[9]) && (iNewReminder <= (table[10]-1)))
  {
   _pcBufferPrecision[iCount] = '9';
   iReminder = iNewReminder - table[9];
  }
  ++iCount;   
 }

 _pcBufferPrecision[iCount] = 0;
}

int main(int argc, char*argv[])
{
 int x = 22;
 int y = 7;
 char BufferPrecision[21];
 int iDigitsAfterDecimalPoint = 20;
 GetRequiredPrecision(x, y, iDigitsAfterDecimalPoint, BufferPrecision);
 printf("after dividing %d by %d, the %d digits after decimal point are\n%s", x, y, iDigitsAfterDecimalPoint, BufferPrecision);
 return 0;
}