-
Notifications
You must be signed in to change notification settings - Fork 37
/
2-1.c
209 lines (170 loc) · 5.73 KB
/
2-1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
* Exercise 2-1. 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.
*
* For signed variables:
* largest negative number is -(2^nbits-1)
* largest positive number is (2^nbits-1)-1
*
* The loop iterates until the variable overflows the positive limit by 1. In
* binary (two's complement), this results in achieving the largest negative
* number with the loop's index and the max number with the result of the
* calculation inside the loop minus 1. Note: we can also achieve the largest
* positive number by negating the loop index and subtract one from it.
* However; the cost of one extra variable (long long max), we gain in code
* clarity.
*
* For unsigned variables:
* min is 0
* max (2^nbits)-1
*
* We do the same for the loop but we iterate the other way: we start from -1 all
* the way up to 0.
*
* for floating point types:
* refer to IEEE 754 standards
*
* By Faisal Saadatmand
*/
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <math.h>
/* functions */
void computeRanges(void);
void stdLibraryMacros(void);
void computeRanges(void)
{
long long unsigned int max;
/* characters */
signed char c;
for (c = max = 1; c > 0; c *= 2)
max *= 2;
printf("signed char\t\t%i\t\t\t%llu\n", c, max - 1);
unsigned char uc;
for (uc = -1; uc < 0; uc *= 2)
max *= 2;
printf("unsigned char\t\t%2i\t\t\t%u\n", 0, uc);
/* Integers */
signed short shrt;
for (shrt = max = 1; shrt > 0; shrt *= 2)
max *= 2;
printf("signed short\t\t%i\t\t\t%llu\n", shrt, max - 1);
unsigned short uShrt;
for (uShrt = -1; uShrt < 0; uShrt *= 2)
max += uShrt;
printf("unsigned short\t\t%2i\t\t\t%u\n", 0, uShrt);
signed int i;
for (i = max = 1; i > 0; i *= 2)
max *= 2;
printf("signed int\t\t%i\t\t%llu\n", i, max - 1);
unsigned int ui;
for (ui = -1; ui < 0; ui *= 2)
;
printf("unsigned int\t\t%2u\t\t\t%u\n", 0, ui);
signed long int li;
for (li = max = 1; li > 0; li *= 2)
max *= 2;
printf("signed long\t\t%li\t%llu\n", li, max - 1);
unsigned long int uli;
for (uli = -1; uli < 0; uli *= 2)
;
printf("unsigned long\t\t%2u\t\t\t%lu\n", 0, uli);
signed long long lli;
for (lli = max = 1; lli > 0; lli *= 2)
max *= 2;
printf("signed long long\t%lli\t%llu\n", lli, max - 1);
unsigned long long ulli;
for (ulli = -1; ulli < 0; ulli *= 2)
;
printf("unsigned long long\t%2i\t\t\t%llu\n", 0, ulli);
printf("\n");
/* floating points */
/* see IEEE 754 standards */
float fltMin, fltMax;
double dblMin, dblMax, mantissa, exponent;
mantissa = 1.0;
exponent = 1.0;
for (i = 0; i < 23; ++i)
mantissa /= 2;
for (i = 0; i < 127; ++i)
exponent *= 2;
fltMin = (2 - mantissa) / exponent;
fltMax = (2 - mantissa) * exponent;
printf("float\t\t\t%g\t\t%g\n", fltMin, fltMax);
mantissa = 1.0;
for (i = 0; i < 52; ++i)
mantissa /= 2;
exponent = pow(2, 1023); /* too big to fit into a variable */
dblMin = (2 - mantissa) / exponent;
dblMax = (2 - mantissa) * exponent;
printf("double\t\t\t%g\t\t%g\n", dblMin, dblMax);
}
void stdLibraryRanges()
{
/* Characters and Integers */
printf("signed char\t\t%.0f\t\t\t%.0f\n",
pow(2, (sizeof(char) * 8 - 1)) * -1,
pow(2, (sizeof(char) * 8) - 1) - 1);
printf("unsigned char\t\t%2i\t\t\t%.0f\n", 0,
pow(2, sizeof(unsigned char) * 8) - 1);
printf("signed short\t\t%.0f\t\t\t%.0f\n",
pow(2, (sizeof(short) * 8 - 1)) * -1,
pow(2, (sizeof(short) * 8) - 1) - 1);
printf("unsigned short\t\t%2i\t\t\t%0.f\n", 0,
pow(2, sizeof(unsigned short) * 8) - 1);
printf("signed int\t\t%.0f\t\t%.0f\n",
pow(2, (sizeof(int) * 8 - 1)) * -1,
pow(2, (sizeof(int) * 8) - 1) - 1);
printf("unsigned int\t\t%2i\t\t\t%0.f\n", 0,
pow(2, sizeof(unsigned int) * 8) - 1);
printf("signed long\t\t%.0f\t%.0Lf\n",
pow(2, (sizeof(long) * 8 - 1)) * -1,
(long double) pow(2, (sizeof(long) * 8) - 1) - 1);
printf("unsigned long\t\t%2i\t\t\t%0.Lf\n", 0,
(long double) pow(2, sizeof(unsigned long) * 8) - 1);
printf("signed long\t\t%.0f\t%.0Lf\n",
pow(2, (sizeof(long long) * 8 - 1)) * -1,
(long double) pow(2, (sizeof(long long) * 8) - 1) - 1);
printf("unsigned long\t\t%2i\t\t\t%0.Lf\n", 0,
(long double) pow(2, sizeof(unsigned long long) * 8) - 1);
printf("\n");
/* floating points */
/* see IEEE 754 standards */
printf("float\t\t\t%g\t\t%g\n",
(2 - pow(2, -23)) / pow(2, 127),(2 - pow(2, -23)) * pow(2, 127));
printf("double\t\t\t%lg\t\t%lg\n",
(2 - pow(2, -52)) / pow(2, 1023), (2 - pow(2, -52)) * pow(2, 1023));
}
void stdLibraryMacros(void)
{
/* characters */
printf("signed char\t\t%i\t\t\t%i\n", CHAR_MIN, CHAR_MAX);
printf("unsigned char\t\t%2i\t\t\t%u\n", 0, UCHAR_MAX);
/* integers */
printf("signed short\t\t%i\t\t\t%i\n", SHRT_MIN, SHRT_MAX);
printf("unsigned short\t\t%2i\t\t\t%u\n", 0, USHRT_MAX);
printf("signed int\t\t%i\t\t%i\n", INT_MIN, INT_MAX);
printf("unsigned int\t\t%2i\t\t\t%u\n", 0, UINT_MAX);
printf("signed long\t\t%li\t%li\n", LONG_MIN, LONG_MAX);
printf("unsigned long\t\t%2i\t\t\t%lu\n", 0, ULONG_MAX);
printf("signed long long\t%lli\t%lli\n", LLONG_MIN, LLONG_MAX);
printf("unsigned long long\t%2i\t\t\t%llu\n", 0, ULLONG_MAX);
printf("\n");
/* floating points */
printf("float\t\t\t%g\t\t%g\n", FLT_MIN, FLT_MAX);
printf("double\t\t\t%lg\t\t%lg\n", DBL_MIN, DBL_MAX);
printf("long double\t\t%Lg\t\t%Lg\n", LDBL_MIN, LDBL_MAX);
}
int main(void)
{
printf("\t**** Computed Manually *****\n");
computeRanges();
printf("\n\t**** Computed Using Library functions *****\n");
stdLibraryRanges();
printf("\n\t**** Printed Using Library Macros in limits.h *****\n");
stdLibraryMacros();
return 0;
}