8

「TheCProgrammingLanguage」第2版の演習2-1を解こうとしています。

「標準ヘッダーから適切な値を出力し、直接計算することにより、符号付きと符号なしの両方のchar、short、int、およびlong変数の範囲を決定するプログラムを作成します。それらを計算する場合は困難です。さまざまな浮動小数点の範囲を決定します。ポイントタイプ。」

標準ヘッダーの最小値と最大値を使用することと、直接計算することの両方によって、浮動小数点を除くすべてのタイプの範囲を決定することができました。

直接計算を使用して浮動小数点型の範囲を決定するにはどうすればよいですか?

#include <stdio.h>
#include <limits.h>
#include <float.h>

#define TESTBIT 2

/* write a program to determine the ranges of char, short, int, and long variables,
   both signed and unsigned by printing appropriate values from standard headers
   and by direct computation

   harder if you compute them - determine the ranges of the various floating-point types */
main()
{
    char ch, chtest;
    unsigned char uch;
    short sh, shtest;
    unsigned short ush;
    int i, itest;
    unsigned int ui;
    long l, ltest;
    unsigned long ul;
    long long ll, lltest;
    unsigned long long ull;

    ch = uch = sh = ush = i = ui = l = ul = ll = ull = 0;
    ++ch;        /* Maximum and minimum ranges using direct computation */
    chtest = 0;
    while (chtest >= 0) {
        chtest = ch * TESTBIT;
        if (chtest > 0)
            ch = ch * TESTBIT;
    }
    ch = ch * 2;
    printf("Minimum range of signed char variable: %d\n", ch);

    --ch;
    printf("Maximum range of signed char variable: %d\n", ch);

    --uch;
    printf("Maximum range of unsigned char variable: %u\n", uch);

    ++sh;
    shtest = 0;
    while (shtest >= 0) {
        shtest = sh * TESTBIT;
        if (shtest > 0)
            sh = sh * TESTBIT;
    }
    sh = sh * 2;
    printf("Minimum range of signed short variable: %d\n", sh);

    --sh;
    printf("Maximum range of signed short variable: %d\n", sh);

    --ush;
    printf("Maximum range of unsigned short variable: %u\n", ush);

    ++i;
    itest = 0;
    while (itest >= 0) {
        itest = i * TESTBIT;
        if (itest > 0)
            i = i * TESTBIT;
    }
    i = i * 2;
    printf("Minimum range of signed int variable: %d\n", i);

    --i;
    printf("Maximum range of signed int variable: %d\n", i);

    --ui;
    printf("Maximum range of unsigned int variable: %u\n", ui);

    ++l;
    ltest = 0;
    while (ltest >= 0) {
        ltest = l * TESTBIT;
        if (ltest > 0)
            l = l * TESTBIT;
    }
    l = l * 2;
    printf("Minimum range of signed long variable: %d\n", l);

    --l;
    printf("Maximum range of signed long variable: %d\n", l);

    --ul;
    printf("Maximum range of unsigned long variable: %lu\n", ul);

    ++ll;
    lltest = 0;
    while (lltest >= 0) {
        lltest = ll * TESTBIT;
        if (lltest > 0)
            ll = ll * TESTBIT;
    }
    ll = ll * 2;
    printf("Minimum range of signed long long variable: %lld\n", ll);

    --ll;
    printf("Maximum range of signed long long variable: %lld\n", ll);

    --ull;
    printf("Maximum range of unsigned long long variable: %llu\n", ull);

    printf("\nSize of char: %d\n", CHAR_BIT);    /* Max and min ranges using limits.h and float.h header */
    printf("Minimum range of signed char variable: %d\n", SCHAR_MIN);
    printf("Maximum range of signed char variable: %d\n", SCHAR_MAX);
    printf("Maximum range of unsigned char variable: %u\n", UCHAR_MAX);
    printf("Minimum range of signed short variable: %d\n", SHRT_MIN);
    printf("Maximum range of signed short variable: %d\n", SHRT_MAX);
    printf("Maximum range of unsigned short variable: %u\n", USHRT_MAX);
    printf("Minimum range of int variable: %d\n", INT_MIN);
    printf("Maximum range of int variable: %d\n", INT_MAX);
    printf("Maximum range of unsigned int variable: %u\n", UINT_MAX);
    printf("Minimum range of signed long variable: %ld\n", LONG_MIN);
    printf("Maximum range of signed long variable: %ld\n", LONG_MAX);
    printf("Maximum range of unsigned long variable: %lu\n", ULONG_MAX);
    printf("Minimum range of long long variable: %lld\n", LLONG_MIN);
    printf("Maximum range of long long variable: %lld\n", LLONG_MAX);
    printf("Maximum range of unsigned long long variable: %llu\n\n", ULONG_LONG_MAX);
    printf("Minimum range of float variable: %f\n", FLT_MIN);
    printf("Maximum range of float variable: %f\n", FLT_MAX);
    printf("Minimum range of double variable: %f\n", DBL_MIN);
    printf("Maximum range of double variable: %f\n", DBL_MAX);
    printf("Minimum range of long double variable: %lf\n", LDBL_MIN);
    printf("Maximum range of long double variable: %lf\n", LDBL_MAX);
    return 0;
}
4

3 に答える 3

4
#include <stdio.h>

main()
{
    float fl, fltest, last;
    double dbl, dbltest, dblast;

    fl = 0.0;
    fltest = 0.0;
    while (fl == 0.0) {
        last = fltest;
        fltest = fltest + 1111e28;
        fl = (fl + fltest) - fltest;
    }
    printf("Maximum range of float variable: %e\n", last);

    dbl = 0.0;
    dbltest = 0.0;
    while (dbl == 0.0) {
        dblast = dbltest;
        dbltest = dbltest + 1111e297;
        dbl = (dbl + dbltest) - dbltest;
    }
    printf("Maximum range of double variable: %e\n", dblast);
    return 0;
}
于 2011-12-01T00:26:59.940 に答える
1

私は最近同じ運動をしました。2の補数とIEEE浮動小数点(単精度と倍精度)を想定して、マシン上で浮動小数点と倍精度のサイズを計算することができました。

特に浮動小数点範囲の計算について、フィードバックをいただければ幸いです。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include <math.h>

int main(int argc, char** argv) {

    printf("-----------Limits Header-----------\n");

    printf("CHAR_BIT    :   %d\n", CHAR_BIT);
    printf("CHAR_MAX    :   %d\n", CHAR_MAX);
    printf("CHAR_MIN    :   %d\n", CHAR_MIN);
    printf("INT_MAX     :   %d\n", INT_MAX);
    printf("INT_MIN     :   %d\n", INT_MIN);
    printf("LONG_MAX    :   %ld\n", (long) LONG_MAX);
    printf("LONG_MIN    :   %ld\n", (long) LONG_MIN);
    printf("SCHAR_MAX   :   %d\n", SCHAR_MAX);
    printf("SCHAR_MIN   :   %d\n", SCHAR_MIN);
    printf("SHRT_MAX    :   %d\n", SHRT_MAX);
    printf("SHRT_MIN    :   %d\n", SHRT_MIN);
    printf("UCHAR_MAX   :   %d\n", UCHAR_MAX);
    printf("UINT_MAX    :   %u\n", (unsigned int) UINT_MAX);
    printf("ULONG_MAX   :   %lu\n", (unsigned long) ULONG_MAX);
    printf("USHRT_MAX   :   %d\n", (unsigned short) USHRT_MAX);
    printf("FLT_MAX     :   %g\n", (float) FLT_MAX);
    printf("-FLT_MAX    :   %g\n", (float) -FLT_MAX);
    printf("FLT_MIN     :   %g\n", (float) FLT_MIN);
    printf("-FLT_MIN    :   %g\n", (float) -FLT_MIN);
    printf("DBL_MAX     :   %g\n", (double) DBL_MAX);
    printf("-DBL_MAX    :   %g\n", (double) -DBL_MAX);
    printf("DBL_MIN     :   %g\n", (double) DBL_MIN);
    printf("-DBL_MIN    :   %g\n", (double) -DBL_MIN);

    printf("\n");
    printf("--------Assuming 2-complement--------\n");
    printf("-----------Computed limits-----------\n");

    char c = 1;
    while (c > 0)
        c *= 2;
    c--;
    printf("Char max    :   %d\n", c);

    c = 1;
    while (c > 0)
        c *= 2;
    printf("Char min    :   %d\n", c);

    int i = 1;
    while (i > 0)
        i *= 2;
    i--;
    printf("Int max     :   %d\n", i);

    i = 1;
    while (i > 0)
        i *= 2;
    printf("Int min     :   %d\n", i);

    long l = 1;
    while (l > 0)
        l *= 2;
    l--;
    printf("Long max    :   %ld\n", l);

    l = 1;
    while (l > 0)
        l *= 2;
    printf("Long min    :   %ld\n", l);

    signed char sc = 1;
    while (sc > 0)
        sc *= 2;
    sc--;
    printf("Sig Char max:   %d\n", sc);

    sc = 1;
    while (sc > 0)
        sc *= 2;
    printf("Sig Char min:   %d\n", sc);

    short si = 1;
    while (si > 0)
        si *= 2;
    si--;
    printf("Sig Int max :   %d\n", si);

    si = 1;
    while (si > 0)
        si *= 2;
    printf("Sig Int min :   %d\n", si);

    unsigned char uc = 1;
    while (uc > 0)
        uc *= 2;
    uc--;
    printf("U Char max  :   %d\n", uc);

    unsigned int ui = 1;
    while (ui > 0)
        ui *= 2;
    ui--;
    printf("U Int max   :   %u\n", ui);

    unsigned long ul = 1;
    while (ul > 0)
        ul *= 2;
    ul--;
    printf("U Long max  :   %lu\n", ul);

    unsigned short us = 1;
    while (us > 0)
        us *= 2;
    us--;
    printf("U Short max :  %u\n", us);

    union {
        int i;
        float f;
    } uf;
    float f;
    for (f = 1; f < INFINITY; uf.f = f, f *= 1e1);
    for (i = 2, f = uf.f; f * i < INFINITY; uf.f = f * i, i++);
    uf.i = uf.i | 0x7FFFFFu; // Mantissa for float is 23 bit on my machine
    printf("FLT max     :   %g (float)\n", uf.f);
    printf("-FLT max    :   %g (float)\n", -uf.f);
    uf.i = uf.i & 0u;
    uf.i = uf.i | 0x7FFFFFu;
    printf("FLT min     :   %g (float)\n", uf.f);
    printf("-FLT min    :   %g (float)\n", -uf.f);

    union {
        long int i;
        double d;
    } ud;
    double d;
    for (d = 1; d < INFINITY; ud.d = d, d *= 1e1);
    for (i = 2, d = ud.d; d * i < INFINITY; ud.d = d * i, i++);
    ud.i = ud.i | 0xFFFFFFFFFFFFFlu; // Mantissa for double is 52 bit on my machine
    printf("DBL max     :   %g (double) \n", ud.d);
    printf("-DBL max    :   %g (double)\n", -ud.d);
    ud.i = ud.i & 0u;
    ud.i = ud.i | 0xFFFFFFFFFFFFFlu;
    printf("DBL min     :   %g (double)\n", ud.d);
    printf("-DBL min    :   %g (double)\n", -ud.d);

    return (EXIT_SUCCESS);
}
于 2015-08-03T10:57:53.763 に答える
0

まず、コードにバグがあるようです。最大値を取得するには、

x = 1;
while(x*2>x)x = x*2 + 1;

それを修正したら、浮動小数点数に同じ式を使用します。

于 2011-11-29T05:10:50.373 に答える