プログラミング

C++ Template Metaprogramming

Posted on Updated on

From my last entry I ended up writing this program while studying Template Metaprogramming:

#include <iostream>

template <int N> struct Factorial {
	static const int result = N * Factorial<N-1>::result;	
};

// describes a specific case of a Factorial
// We need a base case (a way to break out of the recursive loop, which in this case
// is 1)
template <> struct Factorial<0> {
	static const int result = 1;	
};


template <int N, int D> struct Frak {
	static const long Num = N;
	static const long Den = D;
};

template <int N, typename F> struct ScalarMultiplication {
	typedef Frak<N*F::Num, F::Den> result;	
};

int main() {
	typedef Frak<2, 3> Two_Thirds;
	
	typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds;
	std::cout << Four_Thirds::Num << "/" << Four_Thirds::Den << "\n";
	return 0;
}

This looks messy but I finally figured out why the executed result is 4/3, and the reason is pretty simple but hard to notice.

Starting from Main():

int main() {
	typedef Frak<2, 3> Two_Thirds;
	
	typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds;
	std::cout << Four_Thirds::Num << "/" << Four_Thirds::Den << "\n";
	return 0;
}

Two_Thirds is a variable type and its a method call to Frak, which is a blue print to when we call our ScalarMultiplication template.

template <int N, int D> struct Frak {
	static const long Num = N;
	static const long Den = D;
};
template <int N, typename F> struct ScalarMultiplication {
	typedef Frak<N*F::Num, F::Den> result;	
};

// somewhere in Main() ...
int main() {
         // ///	
	typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds;
        // ...
}

N is 2, and F is 3. But looking closely at this line:

typedef Frak<N*F::Num, F::Den> result;	

Our template takes 2 parameters. 2 and 3, and the first parameter is 2 … which is then multiplied by itself to the number 4 and 3 is never calculated. So later when we print the results of this code we will get the answer 4/3

Hopefully if anybody was confused they might find this a little bit clearer … I hope…

EDIT: 2015/04/28
Thanks to nicolasbrailo for clearing up the confusion I had (my bad (d’oh!)) about Two_thirds. It’s not a variable, its a type. Check out his comment below for more details. Thanks bro! ^^
My code after modified according to Nicolas’s comment:

#include <iostream>
 
struct Two_thirds {
    static const long Num = 2;
    static const long Den = 3;
};

int main() {
    std::cout << (Two_thirds::Num*Two_thirds::Num) << "/" << Two_thirds::Den << "\n";
    return 0;
}

Much easier!

Advertisements

Pointers in C++

Posted on Updated on

Following my last entry I decided to take another look at C++ pointers, pointer by reference and pointer by value (It’s still confusing for me so I did this to see if it makes telling the two apart any easier):

#include "pointer_test.h"d
#include <iostream>
 
using namespace std;
 
pointer_test::pointer_test() {
  // constructor
}
 
pointer_test::~pointer_test() {
  // destructor
}
 
int main() {
  int var = 20;
  int *ip;    // pointer reference
 
  ip = &var;
 
  cout << "&var -- " << &var << "\n"; // 0x7fff5b73c828, pointer by value
  cout << "var -- " << var << "\n"; // 20, pointer by reference
 
  cout << "&ip -- " << &ip << "\n"; // 0x7fff5b73c828, pointer by value
  cout << "*ip -- " << *ip << "\n"; // 20, pointer by reference
 
  return 0;
}

Also got a haircut on Sunday in Tenjin. First time going to a Japanese salon and I must say for the price I paid (4000-ish yen) I quite like it. At first I would think paying to get a haircut is stupid if I can do it myself but looking this stylish feels refreshing!

Playing with C++ – Initialization Lists (Quadratic Equation solver source)

Posted on Updated on

Wanted to post this on Monday but I kept getting a weird error on WordPress.
Last year while I worked on a different project using C++ I came across something I had never seen before in C++ called Initialization Lists. It was also the same time that I realized knowing very little about this technology while assuming it is the same as C# is a bad idea.

In my previous project I had stumbled upon a piece of code in a C++ constructor like this:

/*
 * コンストラクタ
 */
ClassName::ClassNameConstructor()
:_int_a()
,_vector_list()
,_bool_init_state()
{

}

What caught my attention first was the colon symbol before what looked like method calls. This is wrong. It’s much easier if you look at the above code like this (for me .. at least):

/*
 * コンストラクタ
 */
ClassName::ClassNameConstructor() :_int_a() ,_vector_list() ,_bool_init_state()
{

}

All this does is initialize our variables in our header file to a value (just in case) and then we can just override their values to anything we want later. I used this example in my quadratic equation solving program like so:

Header file:

// #include "firstSolution.h"
#ifndef _FIRST_SOLUTION_H
#define _FIRST_SOLUTION_H

class firstSolution {
private:
	// 係数
	int a_value;
	int b_value;
	int c_value;

	// 二次方程式
	double quadratic_formula;

protected:
	double result[2];

public:
	firstSolution();   // コンストラクタ
	~firstSolution();  // デストラクタ

	void enterValues();
	void getValues();

	template<typename T> // は?
	T calculateAC(T a, T c);

	template<typename T> // は?
	T calculateTwoA(T a, T two);	
	
	void calculateSquareRoot(int a, int b, int c);
};

#endif // _FIRST_SOLUTION_H

Implementation file:

// rest of the code goes here
firstSolution::firstSolution()
    : a_value(0)
    , b_value(0)
    , c_value(0)
    , quadratic_formula(0)
{
	// 一応これも初期化する(上)
	// コンストラクタ
}
// rest of the code goes here

And all this is, is a different way of writing our constructor like below (dont know if this compiles, just an example):

firstSolution::firstSolution() {
    a_value = 0
    b_value = 0
    c_value = 0
    quadratic_formula = 0
}

Full source of the implementation file:

#include "firstSolution.h"
#include <math.h>
#include <iostream>

using namespace std;

firstSolution::firstSolution()
    : a_value(0)
    , b_value(0)
    , c_value(0)
    , quadratic_formula(0)
{
	// 一応これも初期化する(上)
	// コンストラクタ
}

firstSolution::~firstSolution() {
	// デストラクタ 
}

/*
 * a、b、cの値を取得
 */
void firstSolution::enterValues() {
	cout << "初期化 a = " << a_value << "\n";
	cout << "初期化 b = " << b_value << "\n";
	cout << "初期化 c = " << c_value << "\n";

	// とりあえずこれでいける...
	cout << "二次方程式:ax2 + bx + c = 0" << "\n" << "ax2 + bx - c = 0 の場合は" <<
			"cをマイナス数字で入力してください\n";

	cout << "aの値を入力してください: " << "\n";
	cin >> a_value;

	cout << "bの値を入力してください: " << "\n";
	cin >> b_value;

	cout << "cの値を入力してください: " << "\n";
	cin >> c_value;

	cout << "aの値を [ " <<  a_value << " ]として入力されました。\n";
	cout << "bの値を [ " <<  b_value << " ]として入力されました。\n";
	cout << "cの値を [ " <<  c_value << " ]として入力されました。\n";

	this->calculateSquareRoot(a_value, b_value, c_value);
}

/*
 * 4*(a*c)
 * 入力されたデータは一般化されたのでdoubleかintでも計算できる
 */
template<typename T>
T firstSolution::calculateAC(T a, T c) {
	return a*c;
}

/*
 * 2*a
 * 入力されたデータは一般化されたのでdoubleかintでも計算できる
 */
template<typename T>
T firstSolution::calculateTwoA(T a, T two) {
	return a*two;
}

/*
 * 平方根の計算
 */
void firstSolution::calculateSquareRoot(int a, int b, int c) {
	double ac = this->calculateAC(a, c);
	double atwo = this->calculateTwoA(a, 2);

	quadratic_formula = sqrt((b*b) - (4 * ac));				// ax2 + bx + c = 0
	result[0] = (((b * -1) + quadratic_formula) / atwo);	// 二次方程式(+)
	result[1] = (((b * -1) - quadratic_formula) / atwo);    // 二次方程式(ー)
}

/*
 * 処理された回答を取得
 */
void firstSolution::getValues() {
	cout << "結果 ===========================================" << "\n";
	cout << "b*b = " << b_value*b_value << "\n";
	cout << "ac = " << a_value*c_value << "\n";
	cout << "quadratic_formula = " << quadratic_formula << "\n";
	cout << "quadratic_formula / 2 = " << quadratic_formula / 2<< "\n";

	// 結果
	for(int i = 0; i < 2; i++) {
		cout << "x = [ " <<  result[i] << " ]\n";
	}
}

/*
 *  ax2 * bx + c = 0 は実際にax2 * bx - c = 0になっているか後に判定処理を書く。
 */
int main () {
	firstSolution fs;

	fs.enterValues();
	fs.getValues();
	return 0;
}

Compiling this will print:

benjamin.lo% g++ firstSolution.cpp
benjamin.lo% ./a.out
初期化 a = 0
初期化 b = 0
初期化 c = 0
二次方程式:ax2 + bx + c = 0
ax2 + bx – c = 0 の場合はcをマイナス数字で入力してください
aの値を入力してください:
1
bの値を入力してください:
3
cの値を入力してください:
-4
aの値を [ 1 ]として入力されました。
bの値を [ 3 ]として入力されました。
cの値を [ -4 ]として入力されました。
結果 ===========================================
b*b = 9
ac = -4
quadratic_formula = 5
quadratic_formula / 2 = 2.5
x = [ 1 ]
x = [ -4 ]

Notice that in the terminal we have:

初期化 a = 0
初期化 b = 0
初期化 c = 0

This is a printed result from our enterValues() method which prints the initial values of a_value, b_value, c_value before the user enters their own values for calculation.

Playing with C++ – Pointers

Posted on Updated on

I dreaded pointers for a very long time and still kind of do because of how tricky they are to understand. For practice, I wrote the program below (based from this tutorial http://www.tutorialspoint.com/cplusplus/cpp_pointers.htm):

#include <iostream>

using namespace std;

pointer_test::pointer_test() {
	// constructor
}

pointer_test::~pointer_test() {
	// destructor
}

int main() {
	int var = 20;	// pointer value
	int *ip;		// pointer reference

	ip = &var;

	cout << "Value of var variable: " << var << "\n";
	cout << "value of ip (pointer by reference): " << *ip << "\n";
	cout << "ip (pointer by reference): " << ip << "\n";

	return 0;
}

When executed:

900586-m@benjamin.lo% g++ pointer_test.cpp
900586-m@benjamin.lo% ./a.out
Value of var variable: 20
value of ip (pointer by reference): 20
ip (pointer by reference): 0x7fff4ff65828

What I now understand is that:

– &var will point to the value of what the pointer has as its value.
– ip will also point to the value of what the pointer has as its value (same as above), but, ip’s value is not really defined but is actually referencing to the var pointer’s value.

– *ip will assign its memory address as its value (which is the address of var’s value)

Cool, Hopefully this was easy enough for me to remember later.

Quadratic equation solver with C++ (long post)

Posted on Updated on

I took from the webpage ( http://www.purplemath.com/modules/quadform.htm ) this example:

Here are some examples of how the Quadratic Formula works:

Solve x2 + 3x – 4 = 0
This quadratic happens to factor:

x2 + 3x – 4 = (x + 4)(x – 1) = 0

On paper the process looks like this:

qform02

6 years ago I wrote this Quadratic Equation solver program using C. If you can understand how it works then um .. let me know because I forgot ..

/* **************************************************************
Quadratic Equation solver program
Name: Ben Lo Date: 32/02/09
*************************************************************** */
#include<stdio.h>
#include<math.h> /* include math.h to calculate square root*/
 
double stageOne(int a, int b, int c);
double stageTwo(int b, double tempA, double tempB, double tempC);
double stageThree(int b, double tempA, double tResult);
double stageThreeAdd(int b, double tempA, double tResult);
double stageThreeSubtract(int b, double tempA, double tResult);
 
/* calculate values for x1 with the addition method */
double stageThreeAdd(int b, double tempA, double tResult2) {
double tResult4, tResult3;
 
printf("----------------------\n");
tResult3 = (b - tResult2);
printf("Value of b: %f\n", b);
 
tResult4 = (tResult3 / tempA);
printf("x1 = %f \n", tResult4);
printf("-----------------------\n");
 
}
 
// ================================================================
 
/* calculate values for x2 with subtraction */
double stageThreeSubtract(int b, double tempA, double tResult2) {
double tResult4, tResult3;
 
/* the formula states that when calculating x1 & x2 *
* b must be -b */
printf("-----------------------\n");
tResult3 = (b + tResult2);
printf("Value of b: %f\n", tResult3);
 
tResult4 = (tResult3 / tempA);
printf("x2 = %f \n", tResult4);
printf("------------------------\n");
 
}
 
 
// ===============================================================
 
/* this function works out the 3rd calculation in 2 different ways */
double stageThree(int b, double tempA, double tResult2) {
 
b = -b;
 
stageThreeAdd(b , tempA, tResult2);
stageThreeSubtract(b , tempA, tResult2);
 
}
 
// ===============================================================
 
/* this function works out the 2nd calculation */
double stageTwo(int b, double tempA, double tempB, double tempC) {
float tResult, tResult2;
 
tResult = (tempB + tempC);
tResult2 = sqrt(tResult);
 
printf("( b2-4ac ) : %f\n", tResult);
printf("-b ± sqrt( b2-4ac ) : %f\n", tResult2);
printf("\n");
 
if (tResult
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("ERROR: cannot display square root of this negative number\n");
printf(" as this will create an imaginary number.\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
stageThree(b, tempA, tResult2);
 
}
 
// =================================================================
/* This function works out the first calculation */
double stageOne(int a, int b, int c){
double tempA, tempB, tempC;
 
tempB = (b * b); /* square B */
tempC = ((a * c) * -4); /* times a to c then times it by -4 */
tempA = (a * 2); /* times a by 2 */
 
printf("-b ± sqrt( b2-4ac ) : %f , %f , %f\n",tempA, tempB, tempC);
stageTwo(b, tempA, tempB, tempC);
// call to function stageTwo to calculate further
}
 
/* --------------------------------------------------------------- */
 
int main(){
 
int a, b, c;
 
printf("\n---------------------------------------------.\n");
printf(". .\n");
printf(". x1,2 = -b ± sqrt( b2-4ac ) .\n");
printf(". ------------------- .\n");
printf(". 2a .\n");
printf(". .\n");
printf("---------------------------------------------\n");
printf("Quadratic Equation solver program.\n");
printf("Enter the quadratic parameters a, b and C: \n");
scanf("%d %d %d", &a, &b, &c);
printf("\n");
printf("*********************************************\n");
printf("\n");
 
stageOne(a, b, c);
}

Today I wrote a very quick but clean(er) version of the program I pasted above but this time using C++.

The header file:

// #include "firstSolution.h"
#ifndef _FIRST_SOLUTION_H
#define _FIRST_SOLUTION_H
 
class firstSolution {
private:
    int a_value;
    int b_value;
    int c_value;
    int total;
 
protected:
    int result[2];
 
public:
    firstSolution();   // コンストラクタ
    ~firstSolution();  // デストラクタ
 
    void enterValues();
    void getValues();
    void calculateSquareRoot(int a, int b, int c);
};
 
#endif // _FIRST_SOLUTION_H

And the cpp file:

#include "firstSolution.h"
#include <math.h>
#include <iostream>
 
using namespace std;
 
firstSolution::firstSolution() {
    // コンストラクタ 
}
 
firstSolution::~firstSolution() {
    // デストラクタ 
}
 
/*
 * a、b、cの値を取得
 */
void firstSolution::enterValues() {
    cout << "aの値を入力してください: " << "\n";
    cin >> a_value;
 
    cout << "bの値を入力してください: " << "\n";
    cin >> b_value;
 
    cout << "cの値を入力してください: " << "\n";
    cin >> c_value;
 
    cout << "aの値を [ " <<  a_value << " ]として入力されました。\n";
    cout << "bの値を [ " <<  b_value << " ]として入力されました。\n";
    cout << "cの値を [ " <<  c_value << " ]として入力されました。\n";
 
    this->calculateSquareRoot(a_value, b_value, c_value);
}
 
/*
 * 平方根の計算
 */
void firstSolution::calculateSquareRoot(int a, int b, int c) {
    total = ((b*b) + (4 * (a*c)));                      //ax2 + bx + c = 0
    result[0] = (((b * -1) - (sqrt(total))) / 2);       //平方根計算する前の +
    result[1] = (((b * -1) + sqrt(total)) / 2);         //平方根計算する前の ー
}
 
/*
 * 処理された回答を取得
 */
void firstSolution::getValues() {
    cout << "(+)計算後:" <<  result[0] << "\n";
    cout << "(ー)計算後:" <<  result[1] << "\n";  
}
 
/*
 *  ax2 * bx + c = 0 は実際にax2 * bx - c = 0になっているか後に判定処理を書く。
 */
int main () {
    firstSolution fs;
 
    fs.enterValues();
    fs.getValues();
    return 0;
}

When run, you enter values for a, b, and c and it will calculate (according to the example in the website) the results for you:

aの値を入力してください:
1
bの値を入力してください:
3
cの値を入力してください:
4
aの値を [ 1 ]として入力されました。
bの値を [ 3 ]として入力されました。
cの値を [ 4 ]として入力されました。
(+)計算後:-4
(ー)計算後:1