0

so the intention of the code is that it generate two random numbers between 1 and 100 for a division and i write the answer, then it tells me if its correct or not. For example 59/89 = 0.66 but says its incorrect (im sorry for the bad english)

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int divC = 0; int divI = 0;
    srand(static_cast<unsigned int>(time(0)));

        char exit = 'n' ;
        int divR1 = rand()%100; int divR2 = rand()%100;
            double reDiv= 0; double solution = divR1 / divR2;
                cout << "---------DIVISION---------" << endl;
                cout << "Operation " << divR1 << " / " << divR2 << endl;
                cout << "Answer: ";
                cin >> reDiv;
                    if (reDiv == solution)
                    {
                        cout << "Correct." << endl;
                        divC + 1;
                    }
                    else
                    {
                        cout << "Incorrect" << endl;
                        divI + 1;
                    }
                cout << "EXIT? [Y/N]: ";
                cin >> exit;

    return 0;
}

this is what i made, i hope i explain my problem well

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • 5
    Classic [integer division](https://stackoverflow.com/q/9455271/555045) – harold Jun 24 '23 at 11:25
  • 1
    Or [What is the behavior of integer division?](https://stackoverflow.com/q/3602827/555045) but I wish there was one for C++ specifically (it works the same, but still) – harold Jun 24 '23 at 11:29
  • 1
    Once you fix the integer division problem you'll likely run into [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Retired Ninja Jun 24 '23 at 11:29
  • 1
    @RetiredNinja and problem of "almost equal" – Swift - Friday Pie Jun 24 '23 at 11:47
  • If you only care for 2 digits after the comma and always want to round down, you may want to do `int resultTimes100 = (100* divR1) / divR2; ... if (static_cast(reDiv * 100) == resultTimes100)`. Of course division by 0 would be problematic. You definetly should add logic for preventing a division by 0 to your code. – fabian Jun 24 '23 at 12:05
  • 1
    @harold I guess [Why does dividing two int not yield the right value when assigned to double?](https://stackoverflow.com/q/7571326/995714) can be used – phuclv Jun 24 '23 at 12:09
  • thanks a lot everyone, the posts are helping me so much – LeNobody009 Jun 24 '23 at 12:22

1 Answers1

2

There are two problems in your code:

  • The first is that solution is 0, because an integer division is performed and is only after the computation converted into a double. You must have at least one double term to get a double division:

     double solution = (double)divR1 / divR2;
    
  • The second is that even if the division was correct, it would not meet your expectations because 59/89 is not 0.66, but 0.66292134831460669542. So if you want to allow some degree of approximation, e.g. two digits after the comma, you should do the comparison differently:

    if (abs(reDiv-solution)<0.01)
    

In general, floating point numbers are rarely completely accurate after the decimal. So comparing with some degree of precision, yields more reliable results than making a strict comparison.

My favourite example:

double r1=.01, r0=0.0; 
for (int i=100; i; i--)               // add 100 times 0.01
    r0 += r1; 
cout << r0<<endl                      // result is 1 (rounded at display)
     <<setprecision(20)<<r0 << endl   // but in reality it is not 1 even if it's not far from it
     <<" problem with test: "<< (r0==1.0) <<endl    // direct comparison fails
     <<" reliable test: "<< ( abs(r0-1.0)<0.01 ) << endl;  // check with a 2 digit precision
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • ooh ok,, why do i need to put the "(double)"? – LeNobody009 Jun 24 '23 at 11:49
  • @LeNobody009 `(double)divR1` says that `divR1` is to be converted to `double`. The compiler then understands that you want to divide a double by an int, and that a double division is required. – Christophe Jun 24 '23 at 11:59
  • 3
    @LeNobody009 otherwise the compiler considers both operands of the `/` expressions of type `int` and ` / ` results in an `int` value that is truncated; the conversion of `int` to `double` would happen afterwards. The expression in the answer results in one of the operands to be converted to `double` before the division and if one of the operands of `/` is a `double`, the other gets converted to one before the division happens resulting in the division of 2 floating point values. – fabian Jun 24 '23 at 11:59
  • @LeNobody009 You're welcome! DOn't hesitate to accept the answer if it solved your problem ;-) – Christophe Jun 24 '23 at 12:32