当日のOHP資料です。
Download : sample-001.c ( SJIS 版 )
/*
* 2012/11/16 sample-001.c
*
* a の平方根を求めるために 次方程式 ( x^2 - a = 0 ) の解を、虱潰し法で解く
* ただし、解は、一桁の自然数
*
*/
#include <stdio.h>
/*
*
*/
#define YES 1
#define NO 0
/*
* x^2 - a = 0 ? : 論理式 P に相当する
*/
int check_formula ( int a, int x ) {
if ( x * x - a == 0 ) { /* 方程式を満すか ? */
return YES;
}
return NO;
}
/*
* 方程式 x^2 - a = 0 の解を、x_min 〜 x_max の範囲で探す
* 見付かったら、その値を返す
* もし見付からなかったら、範囲外の数 ( x_max + 1 ) を返す
*/
int solve_formal ( int a, int x_min, int x_max ) {
int x;
for ( x = x_min; x <= x_max; x++ ) { /* x = x_min 〜 x_max */
if ( check_formula ( a, x ) == YES ) { /* 見付かった */
return x; /* その値を返す */
}
}
/*
* 見付からなかったので..
*/
return x_max + 1; /* 範囲の外である数を返す */
}
/*
* x^2 - a = 0 の整数解を求める
*/
int main ( void ) {
int a; /* x^2 - a = 0 の a */
int x_min;
int x_max; /* F = { x | x_min <= x <= x_max } */
int x; /* 答の候補 */
/*
* [Input]
*/
/*
* P(x) == ( x^2 - a = 0 )
*/
printf ( "方程式 x^2 - a = 0 の整数解 ( a の平方根 ) を搜します。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%d", &a );
/*
* F = { x | x_min <= x <= x_max }
*/
printf ( "x の取り得る範囲を指定してください\n" );
printf ( "\t最小値 : " );
scanf ( "%d", &x_min );
printf ( "\t最大値 : " );
scanf ( "%d", &x_max );
/*
* [Process]
*/
/*
* 「 \exists x \in F[P(x)] 」の探索による証明
*/
x = solve_formal ( a, x_min, x_max );
/*
* [Output]
*/
if ( x > x_max ) {
printf ( "方程式 x^2 - %d = 0 の解を %d 〜 %d の範囲の整数からは見つける事ができませんでした。\n", a, \
x_min, x_max );
} else { /* 答が見つかった */
printf ( "方程式 x^2 - %d = 0 の解は %d です。\n", a, x );
}
/*
*
*/
return 0;
}
/*
*
*/
16 0 10
C:\usr\c>sample-001< sample-001.in 方程式 x^2 - a = 0 の整数解 ( a の平方根 ) を搜します。 a の値を入力してください : 16 x の取り得る範囲を指定してください 最小値 : 0 最大値 : 10 方程式 x^2 - 16 = 0 の解は 4 です。 C:\usr\c>
Download : sample-002.c ( SJIS 版 )
/*
* 2012/11/16 sample-002.c
*
* a の平方根を求めるために 次方程式 ( x^2 - a = 0 ) の解を、虱潰し法で解く
* ただし、解は、小数点第ニ位まで求める
*
*/
#include <stdio.h>
#include <math.h> /* abs を利用するので.. */
/*
*/
#define EPSILON (10e-2) /* 精度 (小数点第ニ位) */
/*
* f(x) = x^2 - a の計算を行う (結果は、浮動小数点数型)
*/
double function ( double a, double x ) {
return x * x - a;
}
/*
* 方程式 x^2 - a = 0 の解を、x_min 〜 x_max の範囲で探す
* 見付かったら、その値を返す
* もし見付からなかったら、範囲外の数 ( x_max + 1 ) を返す
*/
double solve_formal ( double a, double x_min, double x_max ) {
double x;
for ( x = x_min; x <= x_max; x = x + EPSILON ) { /* x = x_min 〜 x_max */
/*
* この計算では誤差があるので、
* P(x) は「f(x)=
* ではなく
* P(x) は「 |f(x)| < ε」となる
*
* [注意] fabs は 浮動小数点数の絶対値を計算する
*/
if ( fabs ( function ( a, x ) ) < EPSILON ) {
return x; /* 十分に解に近い値 */
}
}
/*
* 見付からなかったので..
*/
return x_max + 1; /* 範囲の外である数を返す */
}
/*
* x^2 - a = 0 の解を小数点第二位まで求める
*/
int main ( void ) {
double a; /* x^2 - a = 0 の a */
double x_min;
double x_max; /* F = { x | x_min <= x <= x_max } */
double x; /* 答の候補 */
/*
* [Input]
*/
/*
* P(x) == ( x^2 - a = 0 )
*/
printf ( "方程式 x^2 - a = 0 の解 ( a の平方根 ) を小数点第二位まで求めるます。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%lf", &a );
/*
* F = { x | x_min <= x <= x_max }
*/
printf ( "x の取り得る範囲を指定してください\n" );
printf ( "\t最小値 : " );
scanf ( "%lf", &x_min );
printf ( "\t最大値 : " );
scanf ( "%lf", &x_max );
/*
* [Process]
*/
/*
* 「 \exists x \in F[P(x)] 」の探索による証明
*/
x = solve_formal ( a, x_min, x_max );
/*
* [Output]
*/
if ( x > x_max ) {
printf ( "方程式 x^2 - %lf = 0 の解を %lf 〜 %lf の範囲からは見つける事ができませんでした。\n", a, \
x_min, x_max );
} else { /* 答が見つかった */
printf ( "方程式 x^2 - %lf = 0 の解は %lf です。\n", a, x );
printf ( "誤差は %lf です。\n", function ( a, x ) );
}
/*
*
*/
return 0;
}
/*
*
*/
2 0 4
C:\usr\c>sample-002< sample-002.in 方程式 x^2 - a = 0 の解 ( a の平方根 ) を小数点第二位まで求めるます。 a の値を入力してください : 2.000000 x の取り得る範囲を指定してください 最小値 : 0.000000 最大値 : 4.000000 方程式 x^2 - 2.000000 = 0 の解は 1.400000 です。 誤差は -0.040000 です。 C:\usr\c>
Download : sample-003.c ( SJIS 版 )
/*
* 2012/11/16 sample-003.c
*
* a の平方根を求めるために 次方程式 ( x^2 - a = 0 ) の解を、
* 二分法で解く
* ただし、解の精度は 10E-6 とする
*
*/
#include <stdio.h>
/*
*
*/
#define EPSILON (10e-6) /* 精度 */
/*
* f(x) = x^2 - a の計算を行う (結果は、浮動小数点数型)
*/
double function ( double a, double x ) {
return x * x - a;
}
/*
* 方程式 x^2 - a = 0 の解を、
* lower 〜 upper の範囲で二分法で、精度が EPSILON 以下の範囲で求める
* 但し、以下の条件が成立しているものとする
*
* lower < upper
*
* f(lower) < 0 < f(upper)
*
*/
double solve_formal ( double a, double lower, double upper ) {
double x;
while ( upper - lower > EPSILON ) { /* 区間が精度より広い */
double middle = (upper + lower)/2.0; /* 中点を求める */
if ( function ( a, middle ) > 0.0 ) { /* 解は middle の左にある */
upper = middle; /* upper を更新 */
} else { /* 解は middle の右 */
lower = middle; /* lower を更新 */
}
}
/*
* 解は、区間 [ lower, upper ] 内にあり、その範囲は EPSILON 以下
*/
return (upper + lower)/2.0; /* 中点の解として返す */
}
/*
* 方程式 x^2 - a = 0 の解を、二分法で求める
*/
int main ( void ) {
double a; /* x^2 - a = 0 の a */
double x_min;
double x_max; /* F = { x | x_min <= x <= x_max } */
double x; /* 答の候補 */
/*
* [Input]
*/
/*
* P(x) == ( x^2 - a = 0 )
*/
printf ( "方程式 x^2 - a = 0 の解 ( a の平方根 ) を小数点第二位まで求めるます。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%lf", &a );
/*
* F = { x | x_min <= x <= x_max }
*/
printf ( "x の取り得る範囲を指定してください\n" );
printf ( "\t最小値 : " );
scanf ( "%lf", &x_min );
printf ( "\t最大値 : " );
scanf ( "%lf", &x_max );
/*
* [Process]
*/
/*
* 「 \exists x \in F[P(x)] 」の探索による証明
*/
x = solve_formal ( a, x_min, x_max );
/*
* [Output]
*/
printf ( "方程式 x^2 - %lf = 0 の解は %lf です。\n", a, x );
printf ( "誤差は %lf です。\n", function ( a, x ) );
/*
*
*/
return 0;
}
/*
*
*/
2 0 4
C:\usr\c>sample-003< sample-003.in 方程式 x^2 - a = 0 の解 ( a の平方根 ) を小数点第二位まで求めるます。 a の値を入力してください : 2.000000 x の取り得る範囲を指定してください 最小値 : 0.000000 最大値 : 4.000000 方程式 x^2 - 2.000000 = 0 の解は 1.414211 です。 誤差は -0.000006 です。 C:\usr\c>
Download : 20121130-01.c ( SJIS 版 )
/*
* DATE-DIR-QQQQ.c
*
* ニ次方程式 ( a x^2 + b x + c = 0 ) の解を、二分法で解く
* ただし、解の精度は 10E-6 とする
*
*/
#include <stdio.h>
/*
*
*/
#define EPSILON (10e-6) /* 精度 */
/*
* f(x) = a x^2 + b x + c の計算を行う
*/
double function ( double a, double b, double c, double x ) {
return a * x * x + b... ;
/*
** この部分を完成させなさい
*/
}
/*
* 方程式 f(x) = a x^2 + b x + c = 0 の解を、
* lower 〜 upper の範囲で二分法で、精度が EPSILON 以下の範囲で求める
* 但し、以下の条件が成立しているものとする
*
* lower < upper
*
* f(lower) < 0 < f(upper)
*
*/
double solve_formal ( double a, double b, double c, double lower, double \
upper ) {
while ( upper - lower > EPSILON ) { /* 区間が精度より広い */
double middle = (upper + lower)/2.0; /* 中点を求める */
if ( function ( a, b, c, middle ) > 0.0 ) { /* 解は middle の左にある */
/*
** この部分を完成させなさい
*/
} else { /* 解は middle の右 */
lower = middle; /* upper を更新 */
}
}
/*
* 解は、区間 [ lower, upper ] 内にあり、その範囲は EPSILON 以下
*/
return (upper + lower)/2.0; /* 中点の解として返す */
}
/*
* a x^2 + b x + c = 0 の解を
*/
int main ( void ) {
double a;
double b;
double c; /* a x^2 + b x + c = 0 の a, b, c */
double x_min;
double x_max; /* 探索区間は [x_min,x_max] */
double x; /* 答の候補 */
/*
* [Input]
*/
/*
* f(x) = a x^2 + b x + c
*/
printf ( "方程式 a x^2 + b x + c = 0 の解を二分法で搜します。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%lf", &a );
printf ( " b の値を入力してください : " );
scanf ( "%lf", &b );
printf ( " c の値を入力してください : " );
scanf ( "%lf", &c );
/*
* 探索区間 : [x_min,x_max]
*/
printf ( "x の探索区間を入力してください\n" );
printf ( "\t最小値 : " );
scanf ( "%lf", &x_min );
printf ( "\t最大値 : " );
scanf ( "%lf", &x_max );
/*
* [Process]
*/
x = solve_formal ( a, b, c, x_min, x_max );
/*
* [Output]
*/
printf ( "方程式 %lf x^2 + -1.000000 x + -2.000000 = 0 の解は 2.000003 です。\n",a \
);
printf ( "誤差は 0.000009 になります。\n" );
/*
** この部分を完成させなさい
*/
/*
*
*/
return 0;
}
/*
*
*/
1 -1 -2 0 10
C:\usr\c\> 20121130-01 方程式 a x^2 + b x + c = 0 の解を二分法で搜します。 a の値を入力してください : 1.000000 b の値を入力してください : -1.000000 c の値を入力してください : -2.000000 x の探索区間を入力してください 最小値 : 0.000000 最大値 : 10.000000 方程式 1.000000 x^2 + -1.000000 x + -2.000000 = 0 の解は 2.000003 です。 誤差は 0.000009 になります。 C:\usr\c\>
Download : 20121130-02.c ( SJIS 版 )
/*
* DATE-DIR-QQQQ.c
*
* ニ次方程式 ( x^5 + a = 0 ) の解を、二分法で解く
* ただし、解の精度は 10E-6 とする
*
*/
#include <stdio.h>
/*
*
*/
#define EPSILON (10e-6) /* 精度 */
/*
* f(x) = x^5 + a の計算を行う
*/
double function ( double a, double x ) {
/*
** この部分を完成させなさい
*/
}
/*
* 方程式 f(x) = x^5 + a = 0 の解を、
* lower 〜 upper の範囲で二分法で、精度が EPSILON 以下の範囲で求める
* 但し、以下の条件が成立しているものとする
*
* lower < upper
*
* f(lower) < 0 < f(upper)
*
*/
double solve_formal ( double a, double lower, double upper ) {
while ( upper - lower > EPSILON ) { /* 区間が精度より広い */
double middle = (upper + lower)/2.0; /* 中点を求める */
if ( function ( a, middle ) > 0.0 ) { /* 解は middle の左にある */
/*
** この部分を完成させなさい
*/
} else { /* 解は middle の右 */
lower = middle; /* upper を更新 */
}
}
/*
* 解は、区間 [ lower, upper ] 内にあり、その範囲は EPSILON 以下
*/
return (upper + lower)/2.0; /* 中点の解として返す */
}
/*
* a x^2 + b x + c = 0 の解を
*/
int main ( void ) {
double a; /* x^5 + a = 0 の a */
double b;
double c;
double x_min;
double x_max; /* 探索区間は [x_min,x_max] */
double x; /* 答の候補 */
/*
* [Input]
*/
/*
* f(x) = x^5 + a
*/
printf ( "方程式 x^5 + a = 0 の解を二分法で搜します。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%lf", &a );
/*
* 探索区間 : [x_min,x_max]
*/
printf ( "x の探索区間を入力してください\n" );
printf ( "\t最小値 : " );
scanf ( "%lf", &x_min );
printf ( "\t最大値 : " );
scanf ( "%lf", &x_max );
/*
* [Process]
*/
x = solve_formal ( a, x_min, x_max );
/*
* [Output]
*/
/*
** この部分を完成させなさい
*/
/*
*
*/
return 0;
}
/*
*
*/
-2 0 2
C:\usr\c\> 20121130-02 方程式 x^5 + a = 0 の解を二分法で搜します。 a の値を入力してください : -2.000000 x の探索区間を入力してください 最小値 : 0.000000 最大値 : 2.000000 方程式 x^5 + -2.000000 = 0 の解は 1.148701 です。 誤差は 0.000021 になります。 C:\usr\c\>
Download : 20121130-03.c ( SJIS 版 )
/*
* DATE-DIR-QQQQ.c
*
* ニ次方程式 ( a x^2 + b x + c = 0 ) の解を、公式で解く
*
*/
#include <stdio.h>
#include <math.h> /* sqrt を利用するので.. */
/*
* f(x) = a x^2 + b x + c の計算を行う (誤差計算のためにだけ利用)
*/
double function ( double a, double b, double c, double x ) {
/*
** この部分を完成させなさい
*/
}
/*
* 方程式 f(x) = a x^2 + b x + c = 0 の解を、
* 公式の一方
*
* -b + \sqrt{ b^2 - 4 a c }
* x = ---------------------------
* 2 a
* x = ( - b + sqrt( b * b - 4 * a * c ) ) / ( 2 * a )
* x = \frac{-b + \sqrt{ b^2 - 4 a c }}{2a}
*
* を利用して解く。
*/
double solve_formal ( double a, double b, double c ) {
return /* ここに (-b .. ) .. / ( 2 * a ) を記入 */ ;
/*
** この部分を完成させなさい
*/
}
/*
* a x^2 + b x + c = 0 の解を公式で求める
*/
int main ( void ) {
double a;
double b;
double c; /* a x^2 + b x + c = 0 の a, b, c */
double x; /* 答の候補 */
/*
* [Input]
*/
/*
* f(x) = a x^2 + b x + c
*/
printf ( "方程式 a x^2 + b x + c = 0 の解を二分法で搜します。\n" );
printf ( " a の値を入力してください : " );
scanf ( "%lf", &a );
printf ( " b の値を入力してください : " );
scanf ( "%lf", &b );
printf ( " c の値を入力してください : " );
scanf ( "%lf", &c );
/*
* [Process]
*/
x = solve_formal ( a, b, c );
/*
* [Output]
*/
/*
** この部分を完成させなさい
*/
/*
*
*/
return 0;
}
/*
*
*/
1 -1 -2 0 10
C:\usr\c\> 20121130-03 方程式 a x^2 + b x + c = 0 の解を二分法で搜します。 a の値を入力してください : 1.000000 b の値を入力してください : -1.000000 c の値を入力してください : -2.000000 方程式 1.000000 x^2 + -1.000000 x + -2.000000 = 0 の解は 2.000000 です。 誤差は 0.000000 になります。 C:\usr\c\>