Skip to content

Commit 199f2db

Browse files
committed
initial commit
1 parent 98dd84c commit 199f2db

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

chapter03/3-4a.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Exercise 3-4. In a two's complement number representation, our version of
3+
* itoa does not handle the largest negative number, that is, the value of n
4+
* equal to -(2^wordsize-1). Explain why not. Modify it to print that value
5+
* correctly, regardless of the machine on which it runs.
6+
*
7+
* By Faisal Saadatmand
8+
*/
9+
10+
/*
11+
* ANSWER:
12+
* In two's complement number representation, the range of values an int can
13+
* hold is from -(2^wordsize-1) to (2^wordsize-1)-1. The most significant bit
14+
* is the sign bit; however, it also holds a value for negative numbers; thus,
15+
* making the negative limit larger than the positive limit by a value of 1.
16+
* When we negate the largest negative number, -(2^wordsize-1), we get a number
17+
* that is equal to 2^wordsize-1, which is larger than the largest positive
18+
* number, (2^wordsize-1)-1. This will overflow a signed int and cause
19+
* unexpected results. To overcome this, we can use an unsigned int for n. The
20+
* check for whether n is negative or not is taking care of with the assigned
21+
* of n to the int variable sign, in which n is convert to a signed int.
22+
*
23+
* Alternatively, we could avoid negating n altogether and use the abs function
24+
* from stdlib.h to extract the digits. See 3-4a.c.
25+
*/
26+
27+
#include <stdio.h>
28+
#include <stdlib.h>
29+
#include <string.h>
30+
#include <limits.h>
31+
32+
#define MAXLEN 1000
33+
34+
void itoa(int, char []);
35+
void reverse(char []);
36+
37+
/* itoa: convert n to characters in s--abs version */
38+
void itoa(int n, char s[])
39+
{
40+
int i, sign;
41+
42+
sign = n;
43+
i = 0;
44+
do { /* generate digits in revered order */
45+
s[i++] = abs(n % 10) + '0'; /* get next digit */
46+
} while ((n /= 10) != 0);
47+
if (sign < 0)
48+
s[i++] = '-';
49+
s[i] = '\0';
50+
reverse(s);
51+
}
52+
53+
/* reverse: reverse the order of the characters in the string s */
54+
void reverse(char s[])
55+
{
56+
int c, i, j;
57+
58+
for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
59+
c = s[i];
60+
s[i] = s[j];
61+
s[j] = c;
62+
}
63+
}
64+
65+
int main(void)
66+
{
67+
char str[MAXLEN];
68+
69+
itoa(0, str); /* do-while loop is necessary for 0 */
70+
printf("%i -> %s\n", 0, str);
71+
itoa(INT_MAX, str);
72+
printf("%i -> %s\n", INT_MAX, str);
73+
itoa(INT_MIN, str);
74+
printf("%i -> %s\n", INT_MIN, str);
75+
return 0;
76+
}

0 commit comments

Comments
 (0)