8

我正在尝试解决“The C Programming Language”第 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 回答