Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CMPT 112 Assignment 2|Example Solution Rational Numbers I Assignment 2, CMPT 112 Petr Kubon, June 15, 1998, SFU 1 Petr Kubon CMPT 112 Assignment 2|Example Solution Petr Kubon 1 User Documentation Title: Rational Numbers I Origin: Petr Kubon, June 15, 1998, SFU Purpose: The program repeatedly reads a sequence of characters until a blank space is encountered and attempts to analyze the sequence as a rational number. If the attempt is successful, the number is output in a simplied form; otherwise, the user is informed why the analysis failed. Input: The input consists of a sequence of rational numbers, input one at a time. Each rational number is entered as a sequence of characters, terminated by a blank space, and optionally also preceded by blank spaces. Each acceptable number has to conform to one of the following two patterns: 1. fractions : optional minus sign -, followed by nonnegative integer, followed by fraction sign /, followed by nonnegative integer. Ex.: 2/4, -7/8; 2. whole numbers : optional minus sign -, followed by nonnegative integer. Ex.: 5, -13, 0. The program terminates when the user enters 0. Output: Each fraction is output in the simplest form possible by taking into account the greatest common divisor of the numerator and the denominator. For example, 2/4 is output as 1/2, -9/3 as -3, and -7/8 as -7/8. Whole numbers are already in the simplest form and so are output as they are. Error messages: The program catches (and informs the user about) two possible errors: 1) invalid input |when the input sequence of characters does not describe a rational number as specied above; and 2) 0 denominator |when the user entered a fraction which does not dene a rational number because the second integer (the denominator) was specied as 0. Restrictions: The input sequence of characters representing a rational number cannot be longer than 80 characters. If longer numbers are required, the constant MAX_LENGTH has to adjusted and the program recompiled. Method: Each input is read into a string which is then converted into a rational number, if possible. The conversion is done character by character, checking that the input conforms to one of the two permissible types of rational numbers. If the conversion succeeds, the function gcd() is used to nd the greatest common divisor of the numerator and the denominator, which is then used to compute the simplest form of the rational number entered. References: Text of Assignment 2. 2 CMPT 112 Assignment 2|Example Solution Petr Kubon 2 Technical Documentation Structure chart main err_code = getRational( r[2] ) putRational( r[2] ) Simplify( r[2] ) divide_with = gcd( | r[0] |, r[1] ) swap( &| r[0] |, &r[1]) gcd( r, r[1] ) Note: | r[0] | denotes the absolute value of the numerator r[0]. Pseudocode Not needed: see main(). 3 err_handler( err_code ) CMPT 112 Assignment 2|Example Solution Petr Kubon 3 Program Documentation /* * * * * * * */ rational.c - a progam for inputting and printing rational numbers V 1.00, June 14 1998; Created by: Petr Kubon The program repeatedly reads a sequence of characters until a blank space is encountered and attempts to analyze the sequence as a rational number. If the attempt is successful, the number is output in a simplified form; otherwise, the user is informed why the analysis failed. #include <stdio.h> #include <ctype.h> /* contains isspace(), isdigit() */ #define TRUE 1 #define FALSE 0 #define MAX_LENGTH 80 /* function prototypes */ unsigned getRational( int r[2] ); void putRational( int s[2] ); void Simplify( int r[2] ); unsigned gcd( int m, int n ); void swap( int *x, int *y ); void err_handler( int err_code ); int main( void ) { int err_code, done; int rational[2]; done = FALSE; while ( !done ) /* get another number */ { err_code = getRational( rational ); if ( !err_code ) { putRational( rational ); if ( rational[0] == 0 ) done = TRUE; } else /* error, inform the user */ 4 CMPT 112 Assignment 2|Example Solution Petr Kubon err_handler( err_code ); } printf("End of program, have a nice day!\n"); return 0; } /* getRational() reads a sequence of non-blank characters and tries * to interpret it as a rational number. * Calls Simplify() to find the simplest form of a rational number. * Returns: * 1) err_code: error code for the error_handler(), with possible values * 0 (rational number), 1 (invalid input), and 2 (0 denominator); * 2) r[2]: simplified rational number (when err_code = 0) */ unsigned getRational( int r[2] ) { char c; /* input character */ int sign = 1; /* assume the number is positive */ int err_code = 0; /* error code, initialize to 'okay' */ char number[MAX_LENGTH]; /* string for the input */ int i = 0; /* position in the input string */ printf("\nEnter a rational number (0 to stop): "); do c = getchar(); while (isspace(c)); /* skip white space */ while (!isspace(c)) /* read the string */ { number[i] = c; i++; c = getchar(); } number[i] = '\0'; /* close the string */ /* process the string from the beginning */ i = 0; r[0] = r[1] = 0; /* initialize the array for rational number */ if (number[0] == '-') /* negative number */ { sign = -1; i++; } 5 CMPT 112 Assignment 2|Example Solution Petr Kubon while ( isdigit(number[i]) ) /* read the numerator */ { r[0] = 10*r[0] + (number[i] - '0'); /* convert to integer */ i++; } r[0] = sign * r[0]; /* first number done */ if (number[i] == '\0') /* whole number */ r[1] = 1; else /* process second number */ if (number[i] == '/') { i++; while ( isdigit(number[i]) ) /* read and convert the denominator { r[1] = 10*r[1] + (number[i] - '0'); i++; } if (number[i] != '\0') /* something left, wrong input */ err_code = 1; else /* full string processed, check denominator */ if (r[1] == 0) err_code = 2; else /* good input, simplify if necessary */ { if (r[0] == 0) /* special case of simplification: 0 */ r[1] = 1; else if (r[1] != 1) Simplify( r ); } } else /* first number not followed by '/', wrong input */ err_code = 1; return err_code; */ } /* putRational() prints a rational number on the screen in the required form. * RESTRICTION: the input has to be a true rational number (err_code = 0) */ void putRational( int s[2] ) { if ( s[1] == 1 ) /* whole number, no fraction sign */ printf("The (simplified) number is: %d\n", s[0]); else printf("The (simplified) number is: %d/%d\n", s[0], s[1]); return; 6 CMPT 112 Assignment 2|Example Solution Petr Kubon } /* err_handler() informs the user of possible mistakes on input. */ void err_handler( int err_code ) { if ( err_code == 1) printf("Error: invalid input. Enter the value again.\n"); else if ( err_code == 2) printf("Error: 0 denominator. Enter the value again.\n"); else { printf("Error: Program needs debugging, exiting.\n"); exit(1); } return; } /* Simplify() simplifies the rational number by finding the greatest * common divisor of the denominator and the absolute value of the * numerator and dividing both number with the divisor. * Calls gcd() to find the greatest common divisor. * Returns the simplified rational number r[2]. * RESTRICTION: the input has to be a fraction, with numerator != 0 */ void Simplify( int r[2] ) { int divide_with, abs_numerator; if (r[0] < 0) /* compute absolute value of r[0] */ abs_numerator = -r[0]; else abs_numerator = r[0]; divide_with = gcd(abs_numerator,r[1]); if (divide_with > 1) /* need to simplify? */ { r[0] = r[0] / divide_with; r[1] = r[1] / divide_with; } return; } 7 CMPT 112 Assignment 2|Example Solution Petr Kubon /* gcd() recursively computes the greatest common divisor of its two * parameters. * Calls swap() to exchange values of parameters, if necessary. * Returns the greatest common divisor. * RESTRICTION: both parameters have to be POSITIVE. */ unsigned gcd( int m, int n) { int r; if (m > n) swap(&m,&n); /* after, m <= n */ r = n % m; if (r == 0) /* n divisible by m */ return m; else return gcd(r,m); } /* swap() switches the values of 2 integers, pointed to by x and y. */ void swap( int *x, int *y ) { int temp; temp = *x; *x = *y; *y = temp; return; } 8 CMPT 112 Assignment 2|Example Solution 4 Test Runs ancha{petr}82: script Script started, file is typescript ancha{petr}1: a.out Enter a rational number (0 to stop): The (simplified) number is: 7/5 7/5 Enter a rational number (0 to stop): The (simplified) number is: 3 9/3 Enter a rational number (0 to stop): The (simplified) number is: 1/3 3/9 Enter a rational number (0 to stop): The (simplified) number is: -45/23 -45/23 Enter a rational number (0 to stop): The (simplified) number is: -3 -12/4 Enter a rational number (0 to stop): The (simplified) number is: 3333/37 9999/111 Enter a rational number (0 to stop): The (simplified) number is: 9 9999/1111 Enter a rational number (0 to stop): The (simplified) number is: -14 -14 Enter a rational number (0 to stop): The (simplified) number is: 56 56 Enter a rational number (0 to stop): The (simplified) number is: 0 End of program, have a nice day! ancha{petr}2: a.out 0 Enter a rational number (0 to stop): The (simplified) number is: 26/3 78/9 9 Petr Kubon CMPT 112 Assignment 2|Example Solution Petr Kubon Enter a rational number (0 to stop): -80/25 The (simplified) number is: -16/5 Enter a rational number (0 to stop): The (simplified) number is: -1/16 -4/64 Enter a rational number (0 to stop): 45.6 Error: invalid input. Enter the value again. Enter a rational number (0 to stop): 45.6/7 Error: invalid input. Enter the value again. Enter a rational number (0 to stop): The (simplified) number is: 123 123 23 Enter a rational number (0 to stop): The (simplified) number is: Enter a rational number (0 to stop): 4a Error: invalid input. Enter the value again. Enter a rational number (0 to stop): 45/-7 Error: invalid input. Enter the value again. Enter a rational number (0 to stop): 45/76/5 Error: invalid input. Enter the value again. Enter a rational number (0 to stop): The (simplified) number is: 0 End of program, have a nice day! ancha{petr}3: a.out -0/12 Enter a rational number (0 to stop): The (simplified) number is: 13/7 13/7 Enter a rational number (0 to stop): The (simplified) number is: -2/3 -2/3 Enter a rational number (0 to stop): The (simplified) number is: 12 12 10 23 CMPT 112 Assignment 2|Example Solution Enter a rational number (0 to stop): The (simplified) number is: -3 -3 Enter a rational number (0 to stop): +78/6 Error: invalid input. Enter the value again. Enter a rational number (0 to stop): 00 The (simplified) number is: 0 End of program, have a nice day! ancha{petr}4: ^Z ancha{petr}5: Script done on Mon Jun 15 12:55:56 1998 11 Petr Kubon