Programming: Fraction Arithmetic in C++

In summary, the program has been assigned in my intro to programming course, which assumes no previous knowledge of programming. Up to this point we've only been required to write functions that accomplish specific tasks within a program. This is the first time we've been asked to design and write a full program.
  • #1
Dembadon
Gold Member
659
89
This program has been assigned in my intro to programming course, which assumes no previous knowledge of programming. Up to this point we've only been required to write functions that accomplish specific tasks within a program. This is the first time we've been asked to design and write a full program.

Homework Statement



These are the requirements for the program:

a) it will handle any single-digit addition, subtraction, multiplication, and division.

b) as a result of the math, there is a potential for up to three digit results, so the program must handle this

c) as a result of the subtraction process, it is possible to arrive at a negative answer; the program must handle this

d) the program must also manage incorrect input for all four input values and the operator. This means that if any non-digit value is entered as a numerator or denominator, if a zero is entered as a denominator, or if any character other than '+', '-', '*', or '/' is entered as an operator, the user must be informed and the program must be stopped immediately without any further processing

Here are a couple screenshots showing what the TUI looks like after the calculation has been made:
fracprog.png


fracprog2.png

My issue:
I need to do some analysis to determine precisely when the answer will be negative and when the numerator will have two or three digits. I also need to know when the denominator will have two digits. The function used to print the green digits can only print one digit at a time, so I also need to find a way to separate my digits for the answer and print them individually at the correct location on the screen.

Homework Equations


The Attempt at a Solution



I started writing out all the possible fraction values a user could input and discovered that a brute force method here is unreasonable, as I would have to check a few thousand different combinations to get what I'm looking for. I need a more elegant mathematical approach that will lend to a readable and efficient function.

I've reasoned that the denominator can never be larger than 81, since only single digit values are allowed as input, so I do not need to test for a three-digit denominator. However, it is possible to have up to three digits in the numerator, so I will need to test for this and adjust my output to the screen accordingly.
 
Last edited:
Physics news on Phys.org
  • #2
Hi Dembadon! :smile:

You might convert your number to a string and get its length.
 
  • #3
I like Serena said:
Hi Dembadon! :smile:

You might convert your number to a string and get its length.

Hi ILS! :smile:

Your suggestion is very clever. Thank you!
 
  • #4
So you are doing
a/b - c/d

So the program probably has variables for a b c and d. To see if it is negative just say
bool isNegative = a/b - c/d < 0
 
  • #5
Thank you both for the help! The program runs flawlessly. =]
 
  • #6
Speaking of counting digits, just some random ideas that may require additional work:

number_of_digits = int(log10(abs(number)));

while (number /= 10) number_of_digits++;
 
  • #7
Borek said:
Speaking of counting digits, just some random ideas that may require additional work:

number_of_digits = int(log10(abs(number)));

while (number /= 10) number_of_digits++;

Yeah, the log10 version was the first I thought of, but then I thought we would have to turn it into something like:
Code:
if (abs(number) < 1)
{
   number_of_digits = 1;
}
else
{
   number_of_digits = 1 + int(log10(abs(number)) + 0.000000001);
}
 
  • #8
I am far from stating any of these approaches is better, I just wanted to show there are many ways of skinning that cat.
 
  • #9
Just a comment, are you supposed to reduce (simplify) the fractional result, or do you get bonus points for doing this?
 
  • #10
rcgldr said:
Just a comment, are you supposed to reduce (simplify) the fractional result, or do you get bonus points for doing this?

There aren't any bonus points available in this course, unfortunately. I might write a function for reducing the result if, by some miracle, I get some spare time and can remember this assignment.

================================================

Well, I noticed a flaw in my program when doing some last minute testing to see if I could break it.

Since we are required to halt all processing if invalid input is detected, I decided to see what would happen if I just hit enter at one of the integer prompts without giving it an integer. I discovered that a zero is sent! This is problematic; we were given a fully-functional .exe so that we can see how the program is supposed to function. The example program does not do anything when the user presses <enter> without providing values, it just sits there. Oddly enough, this is the way my program behaves when prompting for the operator (which is a character), but it will always send a "zero" when I hit <enter> at the integer prompts.

Where is the zero coming from?
 
Last edited:
  • #11
Which function(s) do you use to read input?
 
  • #12
I like Serena said:
Which function(s) do you use to read input?

Here is the function's prototype:
Code:
/*
name: promptForIntAt
process: prompts user for integer at the specified location, then returns it
input: x, y location, text to prompt user (string)
output/returned: one integer (int) is returned to calling function
dependencies: uses getInputString function
*/
int promptForIntAt( int xPos, int yPos, const string &promptString );
Here is the implementation:
Code:
int promptForIntAt( int xPos, int yPos, const string &promptString )
   {
    // initialize function
    string response;
    int index, numStringLength, answer;
    bool negFlag = false;

    // print prompt string
    mvaddstr( yPos, xPos, promptString.c_str() );

    // move cursor to response point
    xPos += promptString.length();
    move( yPos, xPos );

    // get response from user in string form
    response = getInputString( xPos, yPos, "+-0123456789" );

    // convert string to integer
    numStringLength = response.length();
    index = 0; answer = 0;

    // check for negative sign, if anything entered
    if( ( numStringLength > 0 ) && ( response.at( index ) == '-' ) )
       {
        negFlag = true;
        index++;
       }

    // skip front end zeroes
    while( ( index < numStringLength ) 
             && ( ( response.at( index ) == '0' ) 
                    || ( response.at( index ) == '+' ) ) )
       {
        index ++;
       }

    // verify some number is still there
    if( index >= numStringLength )
       {
        return 0;
       }

    // load number
    while( index < numStringLength )
       {
        answer *= 10;

        answer += int( response.at( index ) - '0' );

        index++;
       }

    if( negFlag )
       {
        answer *= -1;
       }

    // return response
    return answer; 
   }
EDIT: Sorry! The following function is a dependency for the function above:

Prototype:
Code:
/*
name: getInputString (supporting function)
process: allows only specified characters to be input, allows backspace
         returns when ENTER key is pressed
input: x & y locations
input: string of characters allowed for input
output (to screen): shows input process by user
output (returned): string value is returned to calling function
dependencies: uses waitForInput and charInString
*/
string getInputString( int xPos, int yPos, const string &allowedChars );

Implementation:
Code:
string getInputString( int xPos, int yPos, const string &allowedChars )
   {
    // initialize function
    const char SPACE = ' ';
    const char NULL_CHARACTER = '\0';
    int response, index = 0;
    char inputString[ MAX_INPUT_LENGTH ];

    // initialize string in case nothing is entered
    inputString[ 0 ] = '\0';

    // repeatedly capture & process input characters
    // stop when ENTER key is pressed
    do
       {
        // place the cursor
        move( yPos, xPos + index );

        // get the input as an integer
        response = waitForInput( FIXED_WAIT );

        // accept key pad input if used
        switch( response )
           {
            case 465:
               response = '+';
               break;

            case 464:
               response = '-';
               break;

            case 463:
               response = '*';
               break;

            case 458:
               response = '/';
               break;
           }

        // if it is in the allowed list of characters,
        // accept and print it
        if( charInString( response, allowedChars.c_str() ) )
           {
            inputString[ index ] = response;
            inputString[ index + 1 ] = NULL_CHARACTER;

            mvaddch( yPos, xPos + index, response );

            index++;
           }

        // if it is the backspace key, act on it
        else if( response == BACKSPACE_KEY )
           {
            if( index >= 0 )
               {
                if( index > 0 )
                   {
                    index--;
                   }

                inputString[ index ] = NULL_CHARACTER;

                mvaddch( yPos, xPos + index, SPACE );
               }
           } 
       }
    while( ( response != ENTER_KEY ) && ( response != KP_ENTER_KEY ) );

    // return the generated string
    return string( inputString );
   }

Final note: These two functions are part of a header file that our professor wrote for us to use in this assignment, so these functions aren't mine and we are not allowed to modify the header file. =[
 
Last edited:
  • #13
What is the function getInputString() supposed to do if you press Enter?

I'm guessing that if you press Enter, the function getInputString() returns an empty response.
Your function promptForIntAt() returns a zero in that case.
 
  • #14
I like Serena said:
What is the function getInputString() supposed to do if you press Enter?

I'm guessing that if you press Enter, the function getInputString() returns an empty response.
Your function promptForIntAt() returns a zero in that case.

Would this be the NULL_CHARACTER constant I see defined in the function? If so, it has been assigned \0, so I'm still not sure why it is returning the integer zero.

We don't start "while," "for," and "do" concepts until tomorrow when we begin file I/O, so I'm having difficulty following everything in his functions.
 
  • #15
Dembadon said:
Would this be the NULL_CHARACTER constant I see defined in the function? If so, it has been assigned \0, so I'm still not sure why it is returning the integer zero.

We don't start "while," "for," and "do" concepts until tomorrow when we begin file I/O, so I'm having difficulty following everything in his functions.

No, it's not the NULL_CHARACTER constant.

The function getInputString() returns an empty string ("") when you press Enter.
As a result the function promptForIntAt() returns the number 0 when you press Enter.

This means that with the functions of your professor you cannot distinguish between the number 0 and Enter being pressed.

To prevent your program from responding to Enter with a zero, the only option you have now, is to check for the number zero and handle that as an invalid input.
 
  • #16
I like Serena said:
No, it's not the NULL_CHARACTER constant.

The function getInputString() returns an empty string ("") when you press Enter.
As a result the function promptForIntAt() returns the number 0 when you press Enter.

This means that with the functions of your professor you cannot distinguish between the number 0 and Enter being pressed.

To prevent your program from responding to Enter with a zero, the only option you have now, is to check for the number zero and handle that as an invalid input.

I understand. Thank you very much for your help! :smile:
 

Related to Programming: Fraction Arithmetic in C++

1. What is fraction arithmetic?

Fraction arithmetic is the process of performing mathematical operations on fractions, which are numbers represented as a ratio of two integers. These operations include addition, subtraction, multiplication, and division.

2. Why use C++ for fraction arithmetic?

C++ is a high-level programming language that allows for efficient and precise calculations. It also offers built-in data types and operators for working with fractions, making it a convenient choice for performing fraction arithmetic.

3. How do I input fractions in C++?

In C++, fractions can be inputted using the standard input stream (cin) or through user-defined functions. The numerator and denominator of the fraction can be stored as separate integer variables.

4. What happens if I try to divide by zero in fraction arithmetic?

Dividing by zero is undefined in fraction arithmetic, just as it is in regular arithmetic. In C++, attempting to divide by zero will result in an error or unexpected output.

5. Can I simplify fractions in C++?

Yes, you can simplify fractions in C++ by finding the greatest common divisor (GCD) of the numerator and denominator and dividing both by this value. This can be done using a user-defined function or the standard library function gcd() in the library.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
10
Views
1K
  • Programming and Computer Science
Replies
25
Views
569
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
8
Views
2K
Back
Top