Ex12Ans
From Prog0
演習第12回
Contents |
解答例
A問題
A-1 ニュートン法
ファイル名: ex12a1.c
#include <stdio.h> #define EPS 1.0e-6 double f(double, double); double df(double); int main() { double a, x, fx, dfx; a = 2.0; x = a; printf("x(k-1)\t\tfx\t\tdfx\t\tx(k)\t\tf(x,%f)\n", a); while ((fx = f(x, a)) > EPS) { dfx = df(x); printf("%f\t%f\t%f", x, fx, dfx); x = x - fx / dfx; printf("\t%f\t%12.10f\n", x, f(x, a)); } printf("sqrt(%f): %12.10f\n", a, x); return 0; } double f(double x, double a) { return x * x - a; } double df(double x) { return 2.0 * x; }
A-2 数値の桁数
ファイル名: ex12a2.c
#include <stdio.h> int digits(int); int main() { int i, j; printf("正の整数を入力してください:"); scanf("%d", &i); j = digits(i); printf("%d の桁数は %d です\n", i, j); return 0; } int digits(int x) { int keta = 1; while (x /= 10) { keta++; } return keta; }
B問題
B-1 10進数から2進数への変換
ファイル名: ex12b1.c
#include <stdio.h> #define DIGIT 8 void d2b(int); int main() { int n; while (1) { printf("10進数を入力してください:"); scanf("%d", &n); if (n < 0) break; else if (n >= 256) printf("256以上の値が入力されました\n"); else d2b(n); } return 0; } void d2b(int n) { int i, bin[DIGIT]; for (i = 0; i < DIGIT; i++) { bin[i] = n % 2; n /= 2; } for (i = 0; i < DIGIT; i++) printf("%d", bin[DIGIT - 1 - i]); printf("\n"); }
B-2 各桁の数値の和
ファイル名: ex12b2.c
#include <stdio.h> #include <stdlib.h> int digits(int); int get_1_digit(int, int); int main() { int i, val, total = 0; printf("正の整数を入力してください:"); scanf("%d", &val); if (val < 0) { fprintf(stderr, "不正な値が入力されました\n"); exit(8); } for (i = 1; i <= digits(val); i++) total += get_1_digit(val, i); printf("%d の各桁の数値の和は %d です\n", val, total); return 0; } /* ハンドアウトの解 */ int digits(int x) { int keta = 0; while (x > 0) { x /= 10; keta++; } return keta; } /* 別解 int digits(int x) { int keta = 1, y = 10; while ((x / y) > 0) { y *= 10; keta++; } return keta; } */ /* ハンドアウトの解 */ int get_1_digit(int x, int pos) { int i, j; for (i = 1; i < pos; i++) x /= 10; j = x % 10; return j; } /* 別解 int get_1_digit(int x, int pos) { int i, j, k = 1; for (i = 1; i < pos; i++) { k *= 10; } j = x % (k * 10) / k; return j; } */
B-3 10進数を16進数で表示
ファイル名: ex12b3.c
#include <stdio.h> int main() { int n; while (1) { printf("10進数を入力してください:"); scanf("%d", &n); if (n < 0) printf("負の値が入力されました\n"); else break; } printf("%d の16進数は %x です\n", n, n); return 0; }
B-4 四捨五入
ファイル名: ex12b4.c
#include <stdio.h> double round_to(double, int); // プロトタイプ宣言 int main() { double val, rounded; int n; printf("正の実数を入力してください:"); scanf("%lf", &val); printf("小数点以下の桁数を入力してください:"); scanf("%d", &n); rounded = round_to(val, n); printf("%f\n", rounded); return 0; } /* xを四捨五入して小数点以下n桁までにする */ double round_to(double x, int n) { double mul = 1, result; int i; for (i = 0; i < n; i++) // 10のn乗を求める mul *= 10; result = (int)(x * mul + 0.5) / mul; // 四捨五入 return result; // resultの値を戻り値として返す }
Extra問題
E-1 素数判定
ファイル名: ex12e1.c
#include <stdio.h> #define NUM 1000 int isprime(int); int main() { int i, p = 0; for(i = 2; i <= NUM; i++) { if(isprime(i)) { printf("%4d ", i); p++; if(p%10 == 0) printf("\n"); /* 10個表示したら改行 */ } } printf("\n"); return 0; } /* 素数を判定するアルゴリズムには様々な方法があり、性能も異なります。以下に2つの方法を示します。 */ int isprime(int d) { int i; if(d == 2) return 1; /* 2は素数 */ if(d%2 == 0) return 0; /* 2以外の2で割り切れるものは非素数 */ /* 方法1:3からd/2までの奇数で割り切れるかを調査 */ for(i = 3; i < d/2; i += 2) { if(d%i == 0) return 0; /* 割り切れたので非素数 */ } /* 方法2:dは、その平方根より大きな数で初めて割り切れることはないため、3からdの平方根までの奇数を調査(方法1より高速) */ /* for(i = 3; i*i <= d; i += 2) { if(d%i == 0) return 0; } */ return 1; /* 割り切れなかったので素数 */ }