-1

the problem I am doing in c ++, it is quite simple and it is the following.

Read a value of floating point with two decimal places. This represents a monetary value. After this, calculate the smallest possible number of notes and coins on which the value can be decomposed. The considered notes are of 100, 50, 20, 10, 5, 2. The possible coins are of 1, 0.50, 0.25, 0.10, 0.05 and 0.01. Print the message “NOTAS:” followed by the list of notes and the message “MOEDAS:” followed by the list of coins.

input: 576.73

My output:

NOTAS:
5 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
1 nota(s) de R$ 20.00
0 nota(s) de R$ 10.00
1 nota(s) de R$ 5.00
0 nota(s) de R$ 2.00
MOEDAS:
1 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
2 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
3 moeda(s) de R$ 0.01

desired output:

NOTAS:
5 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
1 nota(s) de R$ 20.00
0 nota(s) de R$ 10.00
1 nota(s) de R$ 5.00
0 nota(s) de R$ 2.00
MOEDAS:
1 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
2 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
3 moeda(s) de R$ 0.01

My code:

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int j;
    double money;
    int tickets[] = {100, 50, 20, 10, 5, 2};
    double coins[] = {1.00, 0.50, 0.25, 0.10, 0.05, 0.01};
    cin >> money;
    cout << "NOTAS:\n";
    for(int i = 0; i < 6; i++)
    {
        j = 0;
        while(tickets[i] * j <= money)
            j += 1;
        money -= tickets[i] * (j - 1);
        cout << j - 1 << " nota(s) de R$ " << tickets[i] << ".00\n";
    }
    cout << "MOEDAS:\n";
    for(int i = 0; i < 6; i++)
    {
        j = 0;
        while(coins[i] * j <= money)
            j += 1;
        money -= coins[i] * (j - 1);
        cout << j - 1 << " moeda(s) de R$ " << fixed << setprecision(2) << coins[i] << "\n";
    }
}

I also tried it with the tickets double vector but even so, the judge does not accept my answer, so I changed it and it also tells me wrong answer.

Link https://www.urionlinejudge.com.br/judge/en/problems/view/1021

and the screenshot:

enter image description here

KSIER45
  • 129
  • 1
  • 1
  • 6
  • 1
    The online system is probably running many tests. Your code passed the one example but must fail for others. In general, using floating point for money is a bad idea. [Is floating point math broken?](https://stackoverflow.com/q/588004) – 001 Dec 08 '20 at 17:47
  • I'm just practicing, but I would like to know why this happens, since I also tried it with int variables, but still it tells me wrong answer – KSIER45 Dec 08 '20 at 17:49
  • @JohnnyMopp And if you knew that problem, however, the output is as expected, or am I wrong? They don't just look at the output? If so, I will try to change that specific part of the code – KSIER45 Dec 08 '20 at 17:51
  • @KSIER45 `double coins[] = {1.00, 0.50, 0.25, 0.10, 0.05, 0.01};` -- Except for `1.00`, `0.5`, and `0.25`, those numbers do not have an exact representation in binary. Thus using them for calculations may yield results you don't expect. – PaulMcKenzie Dec 08 '20 at 17:53
  • a beginner friendly environment is one where you know the test cases, you know which pass and which fail, and you can inspect the test cases for detailed debugging. Online competitions is not that. – 463035818_is_not_an_ai Dec 08 '20 at 17:53
  • @largest_prime_is_463035818 I can't understand him very well, however, it is not an online competition, the page is made for practice, or am I wrong? – KSIER45 Dec 08 '20 at 17:56
  • Just because you are to read it as a float doesn't mean you have to do your computations as a float. Maybe int or long would work better for you. – EvilTeach Dec 08 '20 at 17:57
  • @JohnnyMopp It cannot be 0, since it will always increase by 1 in the while, so j - 1 will be equal to 0 – KSIER45 Dec 08 '20 at 17:57
  • @KSIER45 if the input is `0.00`, `j` will never be increased – sebrockm Dec 08 '20 at 17:59
  • Ok. I see that now. Retracted. – 001 Dec 08 '20 at 18:01
  • I ran your code with input of `4.35` and it gave the wrong result: https://ideone.com/nnwjK5. Consider re-writing with integers. – 001 Dec 08 '20 at 18:09
  • I changed it to long and the judge just admitted it, should I do this every time I need to operate with decimals? – KSIER45 Dec 08 '20 at 18:13
  • @JohnnyMopp Let's try it, thank you very much for the contribution – KSIER45 Dec 08 '20 at 18:13
  • @JohnnyMopp Thanks and it is true there is an error, that is given by using operations with decimals? Or is there a problem with my code? – KSIER45 Dec 08 '20 at 18:16
  • 2
    Depending on what the judge uses for a compiler, the first line might not compile. And if it does compile, [don't do it](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). In general, you should not directly include anything from the bits folder. It contains helper files for a particular C++ Standard Library implementation. How these files behave is not guaranteed by the C++ Standard and may not even be consistent from one revision of the same library implementation to the next. – user4581301 Dec 08 '20 at 18:23
  • @KSIER45 Monetary calculations should be done in integer. As soon as you did this `0.10`, you have introduced an inexact value into your program, since `0.10` has no exact binary representation. – PaulMcKenzie Dec 08 '20 at 18:28
  • 1
    Welcome to Stack Overflow! [You should never use #include ](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). – rsjaffe Dec 08 '20 at 19:55
  • The simplest input that fails with the `double` version is `0.06`. – n. m. could be an AI Dec 08 '20 at 20:07
  • @rsjaffeI saw many competitors who do it to save time, in personal projects I do not do it but to save time in that case I do not know what they would recommend? – KSIER45 Dec 11 '20 at 23:21

1 Answers1

0

Thanks to the help of all those who told me that I should not use operations with decimals, taking the error with the example:

>> 0.1 + 0.2 == 0.3 
false

The new code should be more or less like this, because it is still optimizable

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int j;
    long money;
    double moneyF;
    int tickets[] = {10000, 5000, 2000, 1000, 500, 200};
    double coins[] = {100, 50, 25, 10, 5, 1};
    cin >> moneyF;
    money = (long)(moneyF * 100);
    cout << "NOTAS:\n";
    for(int i = 0; i < 6; i++)
    {
        j = 0;
        while(tickets[i] * j <= money)
            j += 1;
        money -= tickets[i] * (j - 1);
        cout << j - 1 << " nota(s) de R$ " << fixed << setprecision(2) << tickets[i] / 100.0 << "\n";
    }
    cout << "MOEDAS:\n";
    for(int i = 0; i < 6; i++)
    {
        j = 0;
        while(coins[i] * j <= money)
            j += 1;
        money -= coins[i] * (j - 1);
        cout << j - 1 << " moeda(s) de R$ " << fixed << setprecision(2) << coins[i] / 100.0 << "\n";
    }
}
KSIER45
  • 129
  • 1
  • 1
  • 6
  • You still may run into issues because you are using floating point to read the user input. I would read as a string and parse that. Also, your inner loops can be replaced with simple math. Here's an example with no fp: https://ideone.com/UPgatW – 001 Dec 09 '20 at 12:27