Commit Diff


commit - 2349130799a9af527e5575e5c6c66e0d2862101a
commit + 9fd524fbcb8213a3da4af6d1dc97cf10de80a0df
blob - /dev/null
blob + ed19af56d34981f7dfe895d3596c2c47865cb340 (mode 644)
--- /dev/null
+++ 3-4-input
@@ -0,0 +1,17 @@
+2147483647
+-2147483648
+5954
+6475
+2558
+10579
+28149
+26450
+4280
+3402
+8696
+30072
+29591
+7140
+14924
+28854
+22352
blob - /dev/null
blob + 82f4c12fbba5cc76778ccd0ee39b5d4b8aabb72b (mode 644)
--- /dev/null
+++ 3-4-output
@@ -0,0 +1,34 @@
+original: 2147483647
+improved: 2147483647
+original: -(
+improved: -2147483648
+original: 5954
+improved: 5954
+original: 6475
+improved: 6475
+original: 2558
+improved: 2558
+original: 10579
+improved: 10579
+original: 28149
+improved: 28149
+original: 26450
+improved: 26450
+original: 4280
+improved: 4280
+original: 3402
+improved: 3402
+original: 8696
+improved: 8696
+original: 30072
+improved: 30072
+original: 29591
+improved: 29591
+original: 7140
+improved: 7140
+original: 14924
+improved: 14924
+original: 28854
+improved: 28854
+original: 22352
+improved: 22352
blob - /dev/null
blob + a3b2481e62f31e87e5aae75adc3f6d54e5058c44 (mode 644)
--- /dev/null
+++ 3-4.c
@@ -0,0 +1,82 @@
+/* 3-4 In a two's complement number representation, our version of itoa does
+ * not handle the largest negative number, that is, the value of n equal to
+ * -2^(wordsize-1). Explain why not. Modify it to print that value correctly,
+ *  regardless of the machine on which it runs.
+ *
+ * When making n positive:
+ *
+ * n = -n;
+ *
+ * In a two's complement system, the most negative integer has a magnitude of
+ * one more than the most positive integer. In other words, the range of an
+ * integer spans from -2^(wordsize-1) to 2^(wordsize-1)-1, including both ends.
+ * 
+ * To fix this, simply */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#define MAXLINE 1000		/* maximum input line size */
+
+void itoa(int n, char s[]);
+void itoa2(int n, char s[]);
+void reverse(char s[]);
+int getlin(char s[], int lim);
+
+int main() {
+	int i;
+	char line[MAXLINE];
+
+	while (scanf("%d\n", &i) == 1) {
+		itoa(i, line);
+		printf("original: %s\n", line);
+		itoa2(i, line);
+		printf("improved: %s\n", line);
+	}
+
+	return 0;
+}
+
+/* itoa: convert n to characters in s */
+void itoa(int n, char s[]) {
+	int i, sign;
+
+	if ((sign = n) < 0) /* record sign */
+		n = -n;			/* make n positive */
+	i = 0;
+	do {				/* generate digits in reverse order */
+		s[i++] = n % 10 + '0';		/* get next digit */
+	} while ((n /= 10) > 0);		/* delete it */
+	if (sign < 0)
+			s[i++] = '-';
+	s[i] = '\0';
+	reverse(s);
+}
+
+
+/* itoa2: convert n to characters in s, modified to handle largest negative
+ * numbers on two's complement machines */
+void itoa2(int n, char s[]) {
+	int i, sign;
+	unsigned u = (unsigned) n;	/* u has same bit sequences as n */
+
+	if ((sign = n) < 0) /* record sign */
+		u = ~u + 1;		/* make u equal to absolute value of n */
+	i = 0;
+	do {				/* generate digits in reverse order */
+		s[i++] = u % 10 + '0';		/* get next digit */
+	} while ((u /= 10) > 0);		/* delete it */
+	if (sign < 0)
+			s[i++] = '-';
+	s[i] = '\0';
+	reverse(s);
+}
+
+/* reverse: reverse string s in place */
+void reverse(char s[]) {
+	int c, i, j;
+	for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
+		c = s[i], s[i] = s[j], s[j] = c;
+	}
+}