Ex12Ans

From Prog0

Jump to: navigation, search

演習第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; /* 割り切れなかったので素数 */
}
Personal tools