|
3 | 3 | * itoa does not handle the largest negative number, that is, the value of n
|
4 | 4 | * equal to -(2^wordsize-1). Explain why not. Modify it to print that value
|
5 | 5 | * correctly, regardless of the machine on which it runs.
|
6 |
| - * By Faisal Saadatmand |
| 6 | + * |
| 7 | + * Answer: In two's complement number representation, the limit ranges from |
| 8 | + * -(2^wordsize-1) to (2^wordsize-1)-1. The most significant bit is the sign |
| 9 | + * bit; however, it also holds a value for negative numbers; thus, making the |
| 10 | + * negative limit larger than the positive limit by a value of 1. This makes a |
| 11 | + * binary value of -(2^wordsize-1) equal to 2^wordsize-1, which is larger than |
| 12 | + * (2^wordsize-1)-1. For example, in a 8-bit wordsize, -128 and 128 are |
| 13 | + * represented as 0x80, which is larger than what the largest positive number |
| 14 | + * an 8-bit word can hold, 127 or 0x8f. The itoa function's first assignment |
| 15 | + * instruction is to negate n. In the case n is |
| 16 | + * -(2^worldsize-1), the negation will produce the same binary number, and |
| 17 | + * therefore, the algorithm will fails at the do/while loop. |
| 18 | + * |
| 19 | + * By Faisal Saadatmand |
7 | 20 | */
|
8 | 21 |
|
9 | 22 | #include <stdio.h>
|
10 | 23 | #include <string.h>
|
11 | 24 | #include <limits.h>
|
12 | 25 |
|
13 |
| -/* functions */ |
14 |
| -void reverse(char []); |
15 |
| -void itoa(int, char []); |
16 |
| - |
17 |
| -/* reverse function: reverse string s in place */ |
18 |
| -void reverse(char s[]) |
19 |
| -{ |
20 |
| - int c, i, j; |
| 26 | +#define MAXLEN 100 |
21 | 27 |
|
22 |
| - for (i = 0, j = strlen(s) - 1; i < j; i++, j --) { |
23 |
| - c = s[i]; |
24 |
| - s[i] = s[j]; |
25 |
| - s[j] = c; |
26 |
| - } |
27 |
| -} |
| 28 | +void itoa(int, char []); |
| 29 | +void reverse(char []); |
28 | 30 |
|
29 | 31 | /* itoa: convert n to characters in s */
|
30 | 32 | void itoa(int n, char s[])
|
31 | 33 | {
|
32 |
| - int i, sign, lastDigit; |
| 34 | + int i, sign; |
33 | 35 |
|
34 |
| - lastDigit = 0; |
35 |
| - if (n == INT_MIN) { /* add check for size */ |
36 |
| - lastDigit = (n % 10 * -1) + '0'; /* extract save the last digit */ |
37 |
| - n -= 1; /* reduce n to fit INT_MAX */ |
| 36 | + i = 0; |
| 37 | + if ((sign = n) < 0) { |
| 38 | + s[i++] = -(n % 10) + '0'; /* extract last digit */ |
| 39 | + n /= 10; /* reduce value to fit signed int */ |
| 40 | + n = -n; /* negate value */ |
38 | 41 | }
|
39 | 42 |
|
40 |
| - if ((sign = n) < 0) /* record sign */ |
41 |
| - n = -n; |
42 |
| - |
43 |
| - i = 0; |
44 |
| - do { /* generate digits in reverse order */ |
45 |
| - s[i++] = n % 10 + '0'; /* get next digit */ |
| 43 | + do { |
| 44 | + s[i++] = n % 10 + '0'; |
46 | 45 | } while ((n /= 10) > 0);
|
47 |
| - |
48 | 46 | if (sign < 0)
|
49 | 47 | s[i++] = '-';
|
50 | 48 |
|
51 |
| - if (lastDigit > 0) /* put back saved last digit */ |
52 |
| - s[0] = lastDigit; |
53 |
| - |
54 | 49 | s[i] = '\0';
|
55 |
| - |
56 | 50 | reverse(s);
|
57 | 51 | }
|
58 | 52 |
|
| 53 | +void reverse(char s[]) |
| 54 | +{ |
| 55 | + int c, i, j; |
| 56 | + |
| 57 | + for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { |
| 58 | + c = s[i]; |
| 59 | + s[i] = s[j]; |
| 60 | + s[j] = c; |
| 61 | + } |
| 62 | +} |
| 63 | + |
59 | 64 | int main(void)
|
60 | 65 | {
|
| 66 | + char string[MAXLEN]; |
61 | 67 | int intValue;
|
62 |
| - char stringNumber[64]; |
63 | 68 |
|
64 |
| - printf("Enter integer to convert to a string: "); |
| 69 | + printf("Enter an integer to convert in a string (range: %i to %i):\n", |
| 70 | + INT_MIN, INT_MAX); |
65 | 71 | scanf("%i", &intValue);
|
66 |
| - |
67 |
| - itoa(intValue, stringNumber); |
68 |
| - |
69 |
| - printf("%s\n", stringNumber); |
| 72 | + itoa(intValue, string); |
| 73 | + printf("%s\n", string); |
70 | 74 |
|
71 | 75 | return 0;
|
72 | 76 | }
|
0 commit comments