Download Rational Numbers I

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Addition wikipedia , lookup

Number theory wikipedia , lookup

Continued fraction wikipedia , lookup

System of polynomial equations wikipedia , lookup

Elementary mathematics wikipedia , lookup

Transcript
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