如何使用直接计算确定浮点类型的范围?

发布于 2024-12-18 15:06:15 字数 4462 浏览 0 评论 0原文

我正在尝试解决《C 编程语言》第二版中的练习 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;
}

I'm trying to solve exercise 2-1 from "The C Programming Language", 2nd edition, which asks to:

"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."

I've managed to determine the ranges of all types except floating-points, both by using minimum and maximum values from standard headers and by direct computation.

How do I determine the ranges of floating-point types using direct computation?

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

内心荒芜 2024-12-25 15:06:15
#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;
}
#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;
}
故乡的云 2024-12-25 15:06:15

这些天我也做了同样的练习。我设法在假设 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);
}

I did the same exercise these days. I managed to compute the sizes of floats and doubles on my machine assuming 2-complement and IEEE floating point (single and double precision).

I would appreciate any feedback, in particular about the computation of the floating point ranges.

#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);
}
你对谁都笑 2024-12-25 15:06:15

首先,您的代码中似乎存在错误。要获得最大值,您需要

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

在修复该问题后,对浮点数使用相同的公式。

first off, it seems you have bugs in the code. to get max, you need

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

once fixed that, use the same formula on floating point number.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文