I'm trying to solve exercise 2-1 from "The C Programming Language", 2nd edition, which asks to:
我正在试着解习题2-1,来自第二版的“C编程语言”,要求:
"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."
编写一个程序来确定字符、短、int和长变量的范围,包括有符号的和无符号的,通过从标准头和直接计算输出适当的值。如果你计算它们会更困难:确定各种浮点类型的范围。
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;
}
3 个解决方案
#1
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;
}
#2
1
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).
这些天我做了同样的练习。我成功地计算了我的机器上的浮点数和双精度浮点数的大小,假设是2补和IEEE浮点数(单精度和双精度)。
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);
}
#3
0
first off, it seems you have bugs in the code. to get max, you need
首先,代码中似乎有错误。要得到max,你需要
x = 1;
while(x*2>x)x = x*2 + 1;
once fixed that, use the same formula on floating point number.
一旦固定,在浮点数上使用相同的公式。
#1
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;
}
#2
1
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).
这些天我做了同样的练习。我成功地计算了我的机器上的浮点数和双精度浮点数的大小,假设是2补和IEEE浮点数(单精度和双精度)。
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);
}
#3
0
first off, it seems you have bugs in the code. to get max, you need
首先,代码中似乎有错误。要得到max,你需要
x = 1;
while(x*2>x)x = x*2 + 1;
once fixed that, use the same formula on floating point number.
一旦固定,在浮点数上使用相同的公式。