Anda di halaman 1dari 5

1: // -----------------------------------------------------------------------------

2: // FILENAME: myaod.c
3: // AUTHOR: Chace Burke
4: // DATE: October 6th, 2010
5: //
6: // PURPOSE: Application adds two 8-bit two's complement numbers and
7: // indicates whether the addition of those values would result
8: // in an overflow error.
9: //
10: // DESCRIPTION: Application receives two integers from the command-line upon
11: // execution and determines whether or not the addition of these
12: // values would result in an overflow for 8-bit two's complement
13: // binary addition. The final result of the calculation is written
14: // to standard output, and includes both the binary and decimal
15: // representations of the result (also a two's complement binary
16: // number).
17: //
18: // Errors from the command-line, regarding the integrity of the
19: // data, are handled first. They include: checking if the command-
20: // line usage is correct, if the arguments are valid numerical
21: // representations of integers, and if these integers fall within
22: // the range of what can be represented by an 8-bit two's
23: // complement binary representation.
24: //
25: // Next, the addition of the two arguments is performed indescrim-
26: // inately, proceeded by an evaluation of whether or not the
27: // initial input was such that an overflow was possible. Overflow
28: // errors can only happen (assuming that the two values are valid,
29: // which has already been checked) when operands share the same
30: // sign. There are only two cases: (1) both are positive, or
31: // (2) both are negative. The case regarding operands of opposite
32: // signs can be ignored since the addition in this case cannot
33: // result in an arithmetic overflow error.
34: //
35: // | ASSUME A = operand 1 AND B = operand 2
36: // | MAX VALUE IS (2^n)-1 FOR ALL n-BIT TWO'S COMPLEMENT NUMBERS
37: // | MIN VALUE IS -(2^n) FOR ALL n-BIT TWO'S COMPLEMENT NUMBERS
38: // |
39: // | CASE (1): IF A + B > (2^8)-1
40: // | THEN OVERFLOW
41: // |
42: // | CASE (2): IF A + B < -(2^8)
43: // | THEN OVERFLOW
44: //
45: // ...If an overflow is detected, the user is notified of the
46: // result accompanied by the binary and decimal representations of
47: // the result.
48: //
49: // By this point, if the execution has not halted, this means that
50: // the addition of the operands did not result in an overflow and
51: // the user is notified via standard output, also accompanied by
52: // the binary and decimal representations of the result.
53: //
54: // Application terminates with 0 environment status.
55: //
56: // ALGORITHM:
57: // [A] Check for valid command-line arguments
58: // [1] Check for valid number of arguments
59: // [2] Check each argument for correct integer representation
60: // [i] scan each character of each argument, searching for any
61: // value that fails the isdigit() test (from ctype.h)
62: // [ii] IF !isdigit()
63: // THEN IF READING THE FIRST CHARACTER AND IF '-' (hyphen)
64: // THEN IGNORE THE TEST (because it represents the sign)
65: // ELSE TEST FAILED (return 0)
66: // [iii] TEST SUCCEEDED AT THIS POINT (return 1)
67: // [3] Store the arguments, which are c-strings, as integer values
68: // using atoi()
69: // [4] Check each integer for valid range ( -128 <= n <= 127 )
70: // IF a OR b LIE OUTSIDE OF THE RANGE [-128, 127]
71: // THEN NOTIFY THE USER AND HALT EXECUTION
72: // [B] Perform addition of arguments. Store result in 8-bit variable
73: // [C] Check result of addition for overflow
74: // [1] IF a AND b ARE BOTH NON-NEGATIVE VALUES
75: // THEN PERFORM ADDITION AND IF RESULT > 127 THEN OVERFLOW
76: // [2] IF a AND b ARE BOTH NEGATIVE VALUES
77: // THEN PERFORM ADDITION AND IF RESULT < -128 THEN OVERFLOW
78: // [D] Display successful result of addition.
79: // [E] Return 0 (EXIT SUCCESS) and end execution.
80: //
81: // ALGORITHM FOR is_arg_valid(char*)...
82: //
83: // [A] Iterate through loop while keeping track of the number of iterations
84: // while not currently reading NULL
85: // [B] IF current character IS NOT A NUMERICAL DIGIT
86: // THEN IF loop counter IS ZERO AND current character IS HYPHEN
87: // THEN INCREMENT LOOP COUNTER AND PROCEED WITH THE NEXT ITERATION
88: // ELSE RETURN ZERO
89: // [C] UPON EXITING THE LOOP, THE TEST HAS SUCCEEDED: RETURN ONE
90: //
91: // ALGORITHM FOR print_binary(int)...
92: //
93: // [A] STORE THE INTEGER PARAMETER AS AN 8-BIT CHARACTER VARIABLE bn
94: // [B] FOR i=0 TO i=8
95: // [1] IF i MODULO 4 IS ZERO
96: // THEN WRITE SPACE TO STANDARD OUTPUT
97: // [2] IF bn BITWISE-AND (1 LEFT-SHIFT (7-i)) > 0
98: // THEN PRINT '1' TO STANDARD OUTPUT
99: // ELSE PRINT '0' TO STANDARD OUTPUT
100: // [C] WRITE bn TO STANDARD OUTPUT USING printf("%d", bn).
101: //
102: // --NOTE: By writing the 8-bit character to output and instructing
103: // printf to interpret the binary data as a signed integer,
104: // bn is implicitly converted into a 16-bit integer. The
105: // addition place values beyond the 8th bit are copies of
106: // the 8th bit, thus transferring the work of deciphering the
107: // two's complement value to the compiler.
108:
109: // INCLUDES
110: #include <ctype.h>
111: #include <stdio.h>
112: #include <stdlib.h>
113:
114: // PROGRAM CONSTANTS
115: #define MAX 127
116: #define MIN -128
117:
118: // FUNCTION PROTOTYPES
119: void print_usage();
120: void print_binary(int n);
121: int is_arg_valid(char* s);
122:
123: // -----------------------------------------------------------------------------
124: // -----------------------------------------------------------------------------
125: //
126: // MAIN
127: //
128: // -----------------------------------------------------------------------------
129: // -----------------------------------------------------------------------------
130:
131: int main(int argc, char** argv)
132: {
133: // ---------------------------------------
134: // TEST FOR THE VALIDITY OF INPUT
135: // ---------------------------------------
136:
137: if (argc != 3)
138: {
139: // invalid number of command line arguments
140: printf("USAGE: ./myaod [INT] [INT]\n");
141:
142: exit(1);
143: }
144: else if (!is_arg_valid(argv[1]) || !is_arg_valid(argv[2]))
145: {
146: printf("ERROR: Arguments may only contain characters 0 through 9\n");
147: printf(" with the exception of the negative sign (hyphen: \"-\")");
148: printf("\n when indicating a negative integer value.\n");
149: print_usage();
150:
151: exit(2);
152: }
153:
154: // validity of the data has bee confirmed,
155: // store arguments as integers for
156: // numerical comparisons
157: int a = atoi(argv[1]);
158: int b = atoi(argv[2]);
159:
160: // Check the range of the integers taken from the command-line arguments.
161: // Since this application is dealing with an 8-bit two's complement number,
162: // the valid range is represented by the intervale [-128, 127].
163: if ((a > MAX || a < MIN) || (b > MAX || b < MIN))
164: {
165: printf("ERROR: Integer values must be between %d and %d\n", MIN, MAX);
166: print_usage();
167:
168: exit(3);
169: }
170:
171: // ---------------------------------------
172: // PERFORM ADDITION
173: // ---------------------------------------
174:
175: int result = a + b;
176:
177: // ---------------------------------------
178: // CHECK ADDITION RESULT FOR OVERFLOW
179: // ---------------------------------------
180:
181: if ((a >= 0) && (b >= 0)) // a AND b ARE BOTH POSITIVE...
182: {
183: // if addition result is greater than 127 then OVERFLOW
184: if (result > 127)
185: {
186: printf("Overflow: ");
187: print_binary(result);
188: exit(4);
189: }
190: }
191: else if ((a < 0) && (b < 0)) // a AND b ARE BOTH NEGATIVE...
192: {
193: // if addition result is less than -128 then OVERFLOW
194: if (result < -128)
195: {
196: printf("Overflow: ");
197: print_binary(result);
198: exit(5);
199: }
200: }
201:
202: // ---------------------------------------
203: // DISPLAY SUCCESSFUL RESULT
204: // ---------------------------------------
205:
206: printf("No overflow: ");
207: print_binary(result);
208:
209: return 0; // Return EXIT SUCCESS
210: }
211: // -----------------------------------------------------------------------------
212: // -----------------------------------------------------------------------------
213: //
214: // FUNCTION DEFINITIONS
215: //
216: // -----------------------------------------------------------------------------
217: // -----------------------------------------------------------------------------
218: // FUNCTION: print_usage(void)
219: //
220: // DESCRIPTION: Displays command-line usage to standard output.
221: //
222: void print_usage()
223: {
224: printf("USAGE: ./myaod [INT] [INT]\n");
225: }
226:
227: // -----------------------------------------------------------------------------
228: // FUNCTION: print_binary(int)
229: //
230: // DESCRIPTION: Stores the 16-bit signed integer into an 8-bit char variable,
231: // and then display its value as a binary number followed by
232: // its decimal representation (which is automatically handled
233: // by the printf function)
234: //
235: void print_binary(int n)
236: {
237: char bn = n; // Assign 16-bit INTEGER to 8-bit CHARACTER
238:
239: int i = 0; // Initialize the loop counter
240: for ( ; i < 8; i++)
241: {
242: if (!(i%4)) printf(" "); // insert a space every 4 places (including the
243: // very first position)
244: if (1<<(7-i) & bn) // if the bitwise-and result is greater than
245: printf("1"); // than zero then display a 1 for current
246: else printf("0"); // power of two, else display zero.
247: }
248:
249: printf(" (%d)\n", bn); // display the decimal value of binary 2's comp.
250: }
251:
252: // -----------------------------------------------------------------------------
253: // FUNCTION: is_arg_valid(char*)
254: //
255: // DESCRIPTION: Function receives a character pointer to a c-string, and checks
256: // each character using the isdigit() function (from ctype.h),
257: // while accounting for the single exception of the negative sign,
258: // which should always be located in the 0th position of the
259: // character array. If the test fails, 0 is returned for FALSE,
260: // otherwise 1 is returned for TRUE.
261: //
262: int is_arg_valid(char* s)
263: {
264: int i = 0; // Initialize the loop counter
265: while (s[i] != '\0') // Check each character while not reading NULL
266: {
267: if (!isdigit(s[i])) // Test for non-numerical value.
268: { //
269: if (i == 0 && s[i] == '-') // If the non-numerical value that was
270: { // found is a hyphen ('-') in the 0th
271: ++i; // position, this indicates the sign
272: continue; // of the integer and thus is ignored.
273: } //
274: else return 0; // Return FALSE for all other cases.
275: }
276: ++i;
277: }
278:
279: return 1; // Check has succeeded. Return TRUE.
280: }
281: // -----------------------------------------------------------------------------
282:

Anda mungkin juga menyukai