acl4の開発ログ

2026.03.18(水) #0

2026.03.18(水) #1

2026.03.18(水) #2

2026.03.26(木) #0

2026.03.26(木) #1

2026.03.26(木) #2

// tt0004a.c

#define a_Version 1
#include <acl4.c>

int64_t limit_denominator_sub(int64_t *ary, int n, int64_t *pb)
// nは配列の長さではなく、それよりも1小さい数を渡す. つまり ary[n]が最後のデータ.
{
    int i;
    int64_t a = ary[n], b = 1, t;
    for (i = n - 1; i >= 0; i--) {
        t = ary[i] * a + b;
        b = a;
        a = t;
    }
    *pb = b;
#if 0
    printf("n=%d [", n);
    for (i = 0; i <= n; i++) printf("%d ", (int) ary[i]);
    printf("] %d/%d\n", (int) a, (int) b);
#endif
    return a;
}

int64_t limit_denominator(double x, int64_t bMax, int64_t *pb)
{
    if (x == 0.0) { *pb = 1; return 0; }
    int sign = 1, i;
    if (x < 0.0) { sign = -1; x *= -1.0; }
    int64_t ary[1024], a = 0, b = 0, ta, tb;
    for (i = 0; i < 1024; i++) {
        ary[i] = (int64_t) x;
        ta = limit_denominator_sub(ary, i, &tb);
        if (tb > bMax) break;
        a = ta; b = tb;
        if (i == 1023) break;
        x -= (double) ary[i];
        if (x < 1e-12) break;
        x = 1.0 / x;
    }
    *pb = b;
    return a * sign;
}

int main()
{
    int64_t a, b;
    double x = 3.14159265358979323;
    a = limit_denominator(x, 10,   &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 100,  &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 1000, &b); printf("%d/%d\n\n", (int) a, (int) b);
    x = sqrt(2);
    a = limit_denominator(x, 10,   &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 100,  &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 1000, &b); printf("%d/%d\n\n", (int) a, (int) b);
    x = exp(1);
    a = limit_denominator(x, 10,   &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 100,  &b); printf("%d/%d\n", (int) a, (int) b);
    a = limit_denominator(x, 1000, &b); printf("%d/%d\n\n", (int) a, (int) b);
    return 0;
}
// 実行結果
>tt0004a
22/7
22/7
355/113

7/5
99/70
1393/985

19/7
193/71
1457/536

2026.03.26(木) #3

2026.03.26(木) #4

// tt0004b.c

int64_t limit_denominator2(double x, int64_t bMin, int64_t *pb)
{
    if (x == 0.0) { *pb = 1; return 0; }
    int sign = 1, i;
    if (x < 0.0) { sign = -1; x *= -1.0; }
    int64_t ary[1024], a, b;
    for (i = 0; i < 1024; i++) {
        ary[i] = (int64_t) x;
        a = limit_denominator_sub(ary, i, &b);
        if (b >= bMin || i == 1023) break;
        x -= (double) ary[i];
        if (x < 1e-12) break;
        x = 1.0 / x;
    }
    *pb = b;
    return a * sign;
}

2026.03.26(木) #5

2026.03.27(金) #0


2026.03.27(金) #1

2026.03.29(日) #0

2026.03.29(日) #1

2026.03.30(月) #0

2026.03.31(火) #0

こめんと欄


コメントお名前NameLink

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS