Powered by SmartDoc

ソフトウェア概論A/B (2015/11/27)
Ver. 1.0

2015年11月27日
栗野 俊一
kurino@math.cst.nihon-u.ac.jp
http://edu-gw2.math.cst.nihon-u.ac.jp/~kurino/2015/soft/soft.html
ソフトウェア概論 A/B2015年11月27日 の資料

目次

講義資料

当日の OHP 資料

講義で利用するサンプルプログラム

Download : sample-001.c ( SJIS 版 )

sample-001.c
/*
 * 2015/11/20 sample-001.c
 *	10 進数を 2 進数表示する
 */

#include <stdio.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-001.exe sample-001.c
 *		実行
 *			./sample-001.exe
 */

#include <stdio.h>

/*
 *	2 進数一桁正の 10 進数の int 型の数値を 2 進数で出力する
 */

void print_bin_one ( int value ) {

	 /* 表示は 0 か 1 だが、数値を文字に変換して出力する必要がある */

	 putchar ( '0' + value );
}

/*
 *	零以上の 10 進数の int 型の数値を 2 進数で出力する
 */

void print_positive_bin ( int value ) {

	 if ( value > 0 ) {	/* 値が正ということは、零でないってこと */
	 	/* まず上位部分を表示 */
		print_positive_bin ( value / 2 );
	 	/* その後で、末尾の一桁の部分を表示 */
		print_bin_one ( value % 2 );
	 }	/* そうでない時は、零だが.. */
		/* 零の時は何もしなくてよい */
}

/*
 *	10 進数の int 型の数値を 2 進数で出力する
 */

void print_bin ( int value ) {

	 if ( value == 0 ) {	/* 0 の時は */
	 	putchar ( '0' );
	 } else if ( value < 0 ) {	/* 負の時は .. */
		putchar ( '-' );	/* 負符号を表示し.. */
		/* 正の場合の処理ができるようにして.. */
		print_bin ( - value );
	} else {	/* 正の場合 */
		/* 正の場合の処理を行う */
		print_positive_bin ( value );
	}
}

/*
 *
 */

int main ( void ) {

	printf ( "100 の 2 進数表現は " );
	print_bin ( 100 );
	printf ( "となります。\n" );

	return 0;
}

/*
 *
 */
sample-001.c の実行結果
$ ./sample-001.exe
100 の 2 進数表現は 1100100となります。
$ 

Download : sample-002.c ( SJIS 版 )

sample-002.c
/*
 * 2015/11/20 sample-002.c
 *	1/n の総和を計算する
 */

#include <stdio.h>

/*
 *	大きい順に和を求める
 */

double sum ( int n ) {
	double s = 0.0;
	int i;

	for ( i = 1; i <= n; i++ ) {
		s += 1.0/i;
	}

	return s;
}

/*
 *
 */

int main ( void ) {
	int n;

	for ( n = 10; n <= 1000000; n *= 10 ) {
		printf ( "1 〜 %i までの総和 = %16.13f\n", n, sum( n ) );
	}

	return 0;
}

/*
 *
 */
sample-002.c の実行結果
$ ./sample-002.exe
1 〜 10 までの総和 =  2.9289682539683
1 〜 100 までの総和 =  5.1873775176396
1 〜 1000 までの総和 =  7.4854708605503
1 〜 10000 までの総和 =  9.7876060360443
1 〜 100000 までの総和 = 12.0901461298633
1 〜 1000000 までの総和 = 14.3927267228648
$ 

Download : sample-003.c ( SJIS 版 )

sample-003.c
/*
 * 2015/11/20 sample-003.c
 *	1/n の総和を計算する
 */

#include <stdio.h>

/*
 *	小さい順に和を求める
 */

double sum ( int n ) {
	double s = 0.0;
	int i;

	for ( i = n; i > 0; i-- ) {
		s += 1.0/i;
	}

	return s;
}

/*
 *
 */

int main ( void ) {
	int n;

	for ( n = 10; n <= 1000000; n *= 10 ) {
		printf ( "1 〜 %i までの総和 = %16.13f\n", n, sum( n ) );
	}

	return 0;
}

/*
 *
 */
sample-003.c の実行結果
$ ./sample-003.exe
1 〜 10 までの総和 =  2.9289682539683
1 〜 100 までの総和 =  5.1873775176396
1 〜 1000 までの総和 =  7.4854708605503
1 〜 10000 までの総和 =  9.7876060360444
1 〜 100000 までの総和 = 12.0901461298634
1 〜 1000000 までの総和 = 14.3927267228658
$ 

Download : sample-004.c ( SJIS 版 )

sample-004.c
/*
 * 2015/11/20 sample-004.c
 *  実解を持つ二次方程式の解を公式で計算する
 */

#include <stdio.h>
#include <math.h>	/* 平方根を求めるために sqrt を利用するので */

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-004.exe sample-004.c -lm
 *		実行
 *			./sample-004.exe
 *
 */

void print_result ( double a, double b, double c ) {
	double d;	/* 判別式の値を保持する */
	double x1;	/* 一つ目の解 */
	double x2;	/* 二つ目の解 */

	/* 判別式の値を計算 */
	d = b * b - 4.0 * a * c;

	if ( d < 0 ) {
		printf ( "この版では、虚解は対応しません。\n" );
	} else {

			/* 公式で計算 */

		x1 = (-b + sqrt ( d ))/(2.0*a);
		x2 = (-b - sqrt ( d ))/(2.0*a);

		printf ( "答え : %16.13f (誤差:%16.13f), %16.13f (誤差:%16.13f)\n",
		   x1, a * x1 * x1 + b * x1 + c,
		   x2, a * x2 * x2 + b * x2 + c
		);
	}
}

/*
 * 方程式と結果を出力
 */

void print_qa ( double b, double c ) {

	printf ( "方程式 x^2 + %f x + %f = 0 の解は\n", b, c );
	print_result ( 1.0, b, c );
	printf ( "\n" );

}

/*
 *
 */

int main ( void ) {

	print_qa ( 2.0, 1.0 );
	print_qa ( -3.0, 2.0 );
	print_qa ( 10000000000.0, 1.0 );

    return 0;

}

/*
 *
 */
sample-004.c の実行結果
$ ./sample-004.exe
方程式 x^2 + 2.000000 x + 1.000000 = 0 の解は
答え : -1.0000000000000 (誤差: 0.0000000000000), -1.0000000000000 \
    (誤差: 0.0000000000000)

方程式 x^2 + -3.000000 x + 2.000000 = 0 の解は
答え : 2.0000000000000 (誤差: 0.0000000000000), 1.0000000000000 (誤差: \
    0.0000000000000)

方程式 x^2 + 10000000000.000000 x + 1.000000 = 0 の解は
答え : 0.0000000000000 (誤差: 1.0000000000000), \
    -10000000000.0000000000000 (誤差: 1.0000000000000)

$ 

本日の課題

課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。

課題 20151127-01 : 10 進数整数値を 16 進で出力する

Download : 20151127-01.c ( SJIS 版 )

20151127-01.c
/*
 * 20151127-01-QQQQ.c
 *	10 進数整数値を 16 進で出力する
 */

#include <stdio.h>

/*
 *	16 進数一桁正の 10 進数の int 型の数値を 16 進数で出力する
 */

void print_hex_one ( int value ) {

	 if ( value < 10 ) {	/* 10 未満であれば .. */
			/* 普通の数字を出力 */
	 	putchar ( value + '0' );
	} else { /* 10 以上の場合は... */
		/* アルファベットを「数字」として利用する */

	/*
	**	 この部分を完成させなさい
	*/

	}			
}

/*
 *	零以上の 10 進数の int 型の数値を 16 進数で出力する
 */

void print_positive_hex ( int value ) {

	 if ( value > 0 ) {	/* 値が正ということは、零でないってこと */
	 	/* まず上位部分を表示 */

	/*
	**	 この部分を完成させなさい
	*/

	 	/* その後で、末尾の一桁の部分を表示 */
		print_hex_one ( value % 16 );
	 }	/* そうでない時は、零だが.. */
		/* 零の時は何もしなくてよい */
}

/*
 *	10 進数の int 型の数値を 16 進数で出力する
 */

void print_hex ( int value ) {

	 if ( value == 0 ) {	/* 0 の時は */
	 	putchar ( '0' );
	 } else if ( value < 0 ) {	/* 負の時は .. */
		putchar ( '-' );	/* 負符号を表示し.. */
		/* 正の場合の処理ができるようにして.. */

	/*
	**	 この部分を完成させなさい
	*/

	} else {	/* 正の場合 */
		/* 正の場合の処理を行う */
		print_positive_hex ( value );
	}
}

/*
 *
 */

int main ( void ) {

	printf ( "100 の 16 進数表現は " );
	print_hex ( 100 );
	printf ( " となります。\n" );

	return 0;
}

/*
 *
 */
入力例
2.3
9.1
5.9
2.7
3.2
20151127-01.c の実行結果
$ ./20151127-01-QQQQ.exe
100 の 16 進数表現は 64 となります。
$ 

課題 20151127-02 : 二次方程式の根を桁落しないように求める

Download : 20151127-02.c ( SJIS 版 )

20151127-02.c
/*
 * 20151120-02-QQQQ.c
 *  二次方程式の根を桁落しないように求める
 */

#include <stdio.h>
#include <math.h>	/* 平方根を求めるために sqrt を利用するので */

/*
 * 利用方法
 *		コンパイル
 *			cc -o 20151120-02-QQQQ.exe 20151120-02-QQQQ.c -lm
 *		実行
 *			./20151120-02-QQQQ.exe
 *
 */

void print_result ( double a, double b, double c ) {
	double d;	/* 判別式の値を保持する */
	double bu;	/* 一つ目の解の分子 */
	double x1;	/* 一つ目の解 */
	double x2;	/* 二つ目の解 */

	/* 判別式の値を計算 */

	/*
	**	 この部分を完成させなさい
	*/


	if ( d < 0 ) {
		printf ( "この版では、虚解は対応しません。\n" );
	} else {
		if ( b < 0 ) {	/* b の符号を見て、桁落の起きないように分子を計算 */
			bu = - b + sqrt ( d );
		} else {

	/*
	**	 この部分を完成させなさい
	*/

		}

		x1 = bu / ( 2.0 * a );	/* 一つ目の解 */

		/* 二つ目の解は、根と係数の関係を利用 */

	/*
	**	 この部分を完成させなさい
	*/


		printf ( "答え : %16.13f (誤差:%16.13f), %16.13f (誤差:%16.13f)\n",
			   x1, a * x1 * x1 + b * x1 + c,
			   x2, a * x2 * x2 + b * x2 + c
		);
	}

}

/*
 * 方程式と結果を出力
 */

void print_qa ( double b, double c ) {

	printf ( "方程式 x^2 + %f x + %f = 0 の解は\n", b, c );
	print_result ( 1.0, b, c );
	printf ( "\n" );

}

/*
 *
 */

int main ( void ) {

	print_qa ( 2.0, 1.0 );
	print_qa ( -3.0, 2.0 );
	print_qa ( 10000000000.0, 1.0 );

    return 0;

}

/*
 *
 */
入力例
123
987
456
20151127-02.c の実行結果
$ ./20151127-02-QQQQ.exe
方程式 x^2 + 2.000000 x + 1.000000 = 0 の解は
答え : -1.0000000000000 (誤差: 0.0000000000000), -1.0000000000000 \
    (誤差: 0.0000000000000)

方程式 x^2 + -3.000000 x + 2.000000 = 0 の解は
答え : 2.0000000000000 (誤差: 0.0000000000000), 1.0000000000000 (誤差: \
    0.0000000000000)

方程式 x^2 + 10000000000.000000 x + 1.000000 = 0 の解は
答え : -10000000000.0000000000000 (誤差: 1.0000000000000), \
    -0.0000000001000 (誤差:-0.0000000000000)

$