Thursday, January 08, 2015

Passing an array by reference

I am blessed to have colleagues to debate with, interesting ones. Today's was about passing an array as a reference. Usually one ends-up passing the array as pointer and the size in the second parameter.

Given below is the code where one is able to pass to a function an entire array of fixed size:


#include <iostream>

int func10(int (&tenIntArray)[10])
{
for (int i = 0; i < 10; i++)
{
if (i == 0) continue;
tenIntArray[i] = tenIntArray[i - 1] + 1;
}
return 0;
}

// Only to show how it is typedef'd
typedef int FiveIntArray[5];

int func05(FiveIntArray &fiveIntArray)
{
return 0;
}

int main(int argc, char* argv[])
{
int tenIntArr[10] = { 1 };
FiveIntArray fiveIntArr = { 1 };

func10(tenIntArr); // we can't pass fiveIntArr here

for (int i = 0; i < 10; i++)
{
std::cout << tenIntArr[i] << std::endl;
}

func05(fiveIntArr); // a tenIntArr is not acceptable here

return 0;
}


It is easier to understand if one typedef's it.

The general rule with the use of typedef is to write out a declaration as if you were declaring a variable of the type you want. Where the declaration would have given a variable name of the particular type, prefixing the whole thing with typedef gives a new type-name instead. The new type-name can then be used to declare new variables.

Tuesday, January 06, 2015

Monte Carlo simulations to determine the value of PI

Consider a circle with radius R. The area of the circle is PI x R^2. The area of the square that just embeds our circle (as in image below) is (2R)^2.


One takes a print of the image, sticks it on a cardboard and throws a dart at it. The chance the dart will fall within the circle is the ratio of area of the circle to the area of the square.

Chance of dart landing within the circle =  Area of circle 
                                                                    Area of square

                                                                 =  PI x R^2 
                                                                       (2R)^2

                                                                 =  PI x R^2 
                                                                      4 x R^2

4 x (Chance of dart landing within the circle) = PI

Whether the dart is within the circle or beyond the circle is simply determined by the distance at which it is from the centre of the figure (as illustrated).



To determine the chance that a dart thrown at the figure will land within the circle, one throws the dart several times and notes the distance of its landing from the origin. 

The ratio  number of times the dart lands at a distance less than equal to the radius of the circle 
                                                              total number of throws

gives us the probability (i.e. chance) of the dart landing within the circle in total number of throws.

There is no bias expected. Hence, the probability of the dart falling within the quarter circle shown in the red square above is the same as that of the dart falling within the entire circle.

Programatically one now needs to randomly select (x, y) to represent a point at which the dart lands, determine if it is at a distance greater than R or not. If it was a unit circle (i.e. R = 1) the comparisons are a little easier since there is no need to take a root of (x^2 + y^2). 

Below is a program that gives us the probability of selecting a point (x, y) such that it falls in the quarter circle:


#include <iostream>
#include <ctime>

void usage()
{
std::cout << "Usage: find_pi <number of tries>" << std::endl;
return;
}

int main(int argc, char* argv[])
{
if (argc != 2)
{
usage();
return -1;
}

int numTries = atoi(argv[1]);

int total = 0;
int inCircle = 0;

srand(static_cast<unsigned>(time(0)));

for (int total = 0; total < numTries; total++)
{
double x = static_cast<double>(rand()) / RAND_MAX;
double y = static_cast<double>(rand()) / RAND_MAX;
double z = x*x + y*y;

if ((z - 1.0) <= DBL_EPSILON)
{
++inCircle;
}
}

std::cout << (double)inCircle * 4.0 / numTries << std::endl;

return 0;
}

Monday, January 05, 2015

Constant pointer and pointer to a constant, yet another attempt

Master: Appears that 'pointer to a constant' and 'constant pointer' are not understood by so many C++ programmers.

Grasshopper: Ain't that simple, one could not change the value when it is a 'pointer to a constant' while the pointer could not be changed for a 'constant pointer'.

Master: That is what all of them recite like a nursery rhyme, rarely does one tell me what is what.

Grasshopper: Hmm....

Master: Hmm...

Grasshopper: Hmm?

Master: Right, amongst the many attempts around the world the below image is my effort. I really hope this will close the gap that I just noticed.





Grasshopper: I do not think it could be further simplified, I won't ever forget it. Thank you very much.

Master: <Smiles and bows down> We could now talk of the differences in them.

Grasshopper: Which become so obvious now...

Sunday, January 04, 2015

Dynamically assign memory to 2D array of integers

Understanding memory management is critical for C++ programmers. One of my colleagues asks people to write code to assign memory to 2D array of integers. The below program shows an easy way of doing that.


#include <iostream>

typedef int* IntPtr;

int main()
{
const int numCols = 5;
const int numRows = 20;

// assign memory for rows
IntPtr* intPtrArr = new IntPtr[numRows];

// now assign memory for columns in each row
for (int i = 0; i < numRows; i++)
{
intPtrArr[i] = new int[numCols];
}

// now assign values to each element
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
intPtrArr[i][j] = (i + 1)*(j + 1);
}
}

// now print whatever is in the array
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
std::cout << intPtrArr[i][j] << " ";
}
std::cout << std::endl;
}

return 0;
}