1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Programming: Fraction Arithmetic in C++

  1. Mar 25, 2012 #1

    Dembadon

    User Avatar
    Gold Member

    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.

    1. The problem statement, all variables and given/known data

    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.

    2. Relevant equations



    3. 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: Mar 25, 2012
  2. jcsd
  3. Mar 25, 2012 #2

    I like Serena

    User Avatar
    Homework Helper

    Hi Dembadon! :smile:

    You might convert your number to a string and get its length.
     
  4. Mar 25, 2012 #3

    Dembadon

    User Avatar
    Gold Member

    Hi ILS! :smile:

    Your suggestion is very clever. Thank you!
     
  5. Mar 25, 2012 #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
     
  6. Mar 26, 2012 #5

    Dembadon

    User Avatar
    Gold Member

    Thank you both for the help! The program runs flawlessly. =]
     
  7. Mar 26, 2012 #6

    Borek

    User Avatar

    Staff: Mentor

    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++;
     
  8. Mar 26, 2012 #7

    I like Serena

    User Avatar
    Homework Helper

    Yeah, the log10 version was the first I thought of, but then I thought we would have to turn it into something like:
    Code (Text):

    if (abs(number) < 1)
    {
       number_of_digits = 1;
    }
    else
    {
       number_of_digits = 1 + int(log10(abs(number)) + 0.000000001);
    }
     
     
  9. Mar 26, 2012 #8

    Borek

    User Avatar

    Staff: Mentor

    I am far from stating any of these approaches is better, I just wanted to show there are many ways of skinning that cat.
     
  10. Mar 26, 2012 #9

    rcgldr

    User Avatar
    Homework Helper

    Just a comment, are you supposed to reduce (simplify) the fractional result, or do you get bonus points for doing this?
     
  11. Mar 27, 2012 #10

    Dembadon

    User Avatar
    Gold Member

    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: Mar 27, 2012
  12. Mar 27, 2012 #11

    I like Serena

    User Avatar
    Homework Helper

    Which function(s) do you use to read input?
     
  13. Mar 27, 2012 #12

    Dembadon

    User Avatar
    Gold Member

    Here is the function's prototype:
    Code (Text):
    /*
    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 (Text):
    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 (Text):
    /*
    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 (Text):
    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: Mar 27, 2012
  14. Mar 27, 2012 #13

    I like Serena

    User Avatar
    Homework Helper

    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.
     
  15. Mar 27, 2012 #14

    Dembadon

    User Avatar
    Gold Member

    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.
     
  16. Mar 27, 2012 #15

    I like Serena

    User Avatar
    Homework Helper

    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.
     
  17. Mar 27, 2012 #16

    Dembadon

    User Avatar
    Gold Member

    I understand. Thank you very much for your help! :smile:
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Programming: Fraction Arithmetic in C++
  1. Program in C (Replies: 1)

  2. C++ Program (Replies: 17)

Loading...