What's wrong with my code?

I was writing a code in c++ using Visual Studio Community 2017 (with Commom Language Runtime Support (/clr) - Windows Desktop | Windows Console Application) and I find something wrong with my code, my code produce the result below:
0.030000 == 0.030000
0.040000 > 0.030000
0.050000 > 0.030000
0.060000 > 0.030000
0.070000 > 0.030000
0.030000 == 0.030000
0.040000 > 0.030000
0.050000 > 0.030000
0.060000 > 0.030000
0.070000 > 0.030000
0.030000 < 0.040000
0.040000 == 0.040000
0.050000 > 0.040000
0.060000 > 0.040000
0.070000 > 0.040000
0.030000 < 0.050000
0.040000 < 0.050000
0.050000 == 0.050000
0.060000 > 0.050000
0.070000 > 0.050000
0.030000 < 0.060000
0.040000 < 0.060000
0.050000 < 0.060000
0.060000 > 0.060000
0.070000 > 0.060000
0.030000 < 0.060000
0.040000 < 0.060000
0.050000 < 0.060000
0.060000 > 0.060000 here is the problem
0.070000 > 0.060000

Can you see that, 0.060000 > 0.060000, so this result is generate using loop if, I can't understand what is wrong with my code, it is wrong, the right way should be 0.060000 == 0.060000, so, the code that produce this result is below:

// Estatística1073001.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <random>
#include <fstream>
#include <string>
#include <string.h>
#include <direct.h>
#include <time.h>
#include <iomanip>
#include <sstream>
#include <windows.h>
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <msclr/marshal_cppstd.h>
#include <MMSystem.h>
#include <cmath>
#include <cstring>


using namespace std;
using namespace System;
using namespace msclr::interop;
using namespace System::Threading;
//using namespace std::experimental::filesystem;
using std::stringstream;


ofstream writer;


string TesStr = "C:/myfolder/Corrigir erros/";// testando string
double MenDig = 0.01;
double calc = MenDig;

void main()
{
cout << " Software Iniciado" << endl;
//------------------------------------ beginning first part ------------------------------------------------------------------------------------------------
writer.open(TesStr + "log.txt", ios_base::app);
calc = MenDig;
for (int i = 5; i <= 12; i++)
{
calc += MenDig;
if (calc >= (MenDig * 4))
{
//double PorRev = 75.0;//porcentagem para reversão
//double PorTotFatMul = 100.0;//porcentagem total ou fator multiplicador
//double calc2 = ((PorRev * calc) / PorTotFatMul) * PorTotFatMul;
//double calc3 = ((PorRev * calc) / PorTotFatMul);
double calc2 = ((75 * calc) / 100) * 100;
double result = trunc(calc2);
double result2 = result / 100;
//double dois = 2.0;
double calc4 = MenDig * 2;//MenDig * dois;
for (int j = 1; j <= 5; j++)
{
//double armrescalc = calc4 + MenDig;//armazena resultado do cálculo
//calc4 = armrescalc;//calc4 += MenDig;
calc4 += MenDig;
//cout << SomCar << ", " << calc5 << ", " << calc6 << " ----------------------------" << endl;
if (calc4 == result2)
{
cout << fixed << showpoint << setprecision(6);
cout << " " << calc4 << " == " << result2 << endl;
writer << fixed << showpoint << setprecision(6);
writer << " " << calc4 << " == " << result2 << endl;
}
else
{
if (calc4 > result2)
{
cout << fixed << showpoint << setprecision(6);
cout << " " << calc4 << " > " << result2 << endl;
writer << fixed << showpoint << setprecision(6);
writer << " " << calc4 << " > " << result2 << endl;
}
else
{
if (calc4 < result2)
{
cout << fixed << showpoint << setprecision(6);
cout << " " << calc4 << " < " << result2 << endl;
writer << fixed << showpoint << setprecision(6);
writer << " " << calc4 << " < " << result2 << endl;
}
}
}
}
}
}
writer.close();
cout << "\n\n End of first part\n" << endl;
//------------------------------------ beginning second part ------------------------------------------------------------------------------------------------
system("pause");

cout << " Fim" << endl;
//system("pause");
}//



So I tried diferents ways to fix it, but now I surrender. I was compile this code using Visual Studio Community 2019 (with Commom Language Runtime Support (/clr) - Project CLR empty), using the same code before, the diference was a remove #include "stdafx.h" e include the #include "pch.h", it was produce the some wrong result, So, anybody have some idea about what is wrong with my code?


Last edited on
Well I'm surprised that you're even getting something close to what you expect. Remember that floating point math produces approximations not exact results.

Here is the output of your code with a little higher precision:

Software Iniciado
0.02999999999999999889 == 0.02999999999999999889
0.04000000000000000083 > 0.02999999999999999889
0.05000000000000000278 > 0.02999999999999999889
0.06000000000000000472 > 0.02999999999999999889
0.07000000000000000666 > 0.02999999999999999889
0.02999999999999999889 == 0.02999999999999999889
0.04000000000000000083 > 0.02999999999999999889
0.05000000000000000278 > 0.02999999999999999889
0.06000000000000000472 > 0.02999999999999999889
0.07000000000000000666 > 0.02999999999999999889
0.02999999999999999889 < 0.04000000000000000083
0.04000000000000000083 == 0.04000000000000000083
0.05000000000000000278 > 0.04000000000000000083
0.06000000000000000472 > 0.04000000000000000083
0.07000000000000000666 > 0.04000000000000000083
0.02999999999999999889 < 0.05000000000000000278
0.04000000000000000083 < 0.05000000000000000278
0.05000000000000000278 == 0.05000000000000000278
0.06000000000000000472 > 0.05000000000000000278
0.07000000000000000666 > 0.05000000000000000278
0.02999999999999999889 < 0.05999999999999999778
0.04000000000000000083 < 0.05999999999999999778
0.05000000000000000278 < 0.05999999999999999778
0.06000000000000000472 > 0.05999999999999999778
0.07000000000000000666 > 0.05999999999999999778
0.02999999999999999889 < 0.05999999999999999778
0.04000000000000000083 < 0.05999999999999999778
0.05000000000000000278 < 0.05999999999999999778
0.06000000000000000472 > 0.05999999999999999778
0.07000000000000000666 > 0.05999999999999999778


End of first part

Fim


Also note my compiler produces a warning about using the operator== to compare two values.

By the way I compiled this as plain C++.

Change
if (calc4 == result2)
to
if (abs(calc4 - result2)<1.0e-10)

That will keep everyone happy.
Well, about my code, I already found the solution thanks the user lastchance and I can understood the solution thanks the user jlb, the user lastchance and jlb solved my problem, but this experience show me that the computer don't know how to work with accurate numbers, so I can't understood why the numbers is not the number I would like to have, , think about it by yourself, so I declared the variable calc4 with the value 0.02 (double calc4 = MenDig * 2) and I added 0.01 to this variable calc4 (calc4 += MenDig), so, the loop for (for (int j = 1; j <= 5; j++)) should print 0.03, 0.04, 0.05, 0.06 and 0.07, like the code below:

// Estatística1073001.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <random>
#include <fstream>
#include <string>
#include <string.h>
#include <direct.h>
#include <time.h>
#include <iomanip>
#include <sstream>
#include <windows.h>
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <msclr/marshal_cppstd.h>
#include <MMSystem.h>
#include <cmath>
#include <cstring>


using namespace std;
using namespace System;
using namespace msclr::interop;
using namespace System::Threading;
//using namespace std::experimental::filesystem;
using std::stringstream;


ofstream writer;


string TesStr = "C:/myfolder/Corrigir erros/";// testando string
double MenDig = 0.01;
double calc = MenDig;

void main()
{
cout << " Software Iniciado" << endl;
//------------------------------------ beginning first part --------------------------------------------------------------------
double calc4 = MenDig * 2;//MenDig * dois;
for (int j = 1; j <= 5; j++)
{
//double armrescalc = calc4 + MenDig;//armazena resultado do cálculo
//calc4 = armrescalc;//calc4 += MenDig;
calc4 += MenDig;
cout << calc4 << endl;
}
system("pause");
}

So, why I have 0.02999999999999999889 and not 0.03? So, when j = 1, 0.02 + 0.01 (calc4 += MenDig) is equal to 0.03, so I should have 0.03 and not 0.02999999999999999889, it is the same from the others numbers, 0.04000000000000000083 and not 0.04? 0.05000000000000000278 and not 0.05? 0.06000000000000000472 and not 0.06? 0.07000000000000000666 and not 0.07? So, Am I all right? The computer don't know how to work with accurate numbers when work with floating point...
Last edited on
Let me dispel your belief that floating point numbers are in any way accurate.
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Integers are accurate, but have a fairly limited range.
Floating point have a larger (but still nowhere near infinite) dynamic range, but at the expense of fine detail precision.
why I have 0.02999999999999999889 and not 0.03?
The computer represents floating point numbers using scientific notation in base 2. That means instead of having digits that represent 1/10, 1/100, 1/1000 etc., the computer's digits represent 1/2, 1/4, 1/8, 1/16, ... They do it this way because it allows fast calculations and compact storage of numbers.

The problem is that 0.03 cannot be represented exactly in base 2. You might think "well tough! I want it in base 10." That would work for about 15 minutes until you tried to represent, say 1/3. That's can't be represented in base 10 either and you're likely to run into the exact same problem.

So when working with floating point numbers, you have to keep in mind that the values are not exact. However, they are usually very very close.

For example, let's look at those two numbers above. They differ by 0.00000000000000000111 - slightly more than 1 part in a quintillion. To put it into perspective, if you measured the distance from the period at the end of this sentence to a pin prick on PLUTO with this much error, you'd be off by 8mm. That's pretty darned close.
Last edited on
I’m so grateful to you for help me with it. Now I feel I am ready to write my code without error, I write software by myself for my own use, I study stock market using c++ and my dream is one day be professional Trader, I hope have my own software in c++ with .dll having interaction with mql4, if it will happend one day, it is because the help you gived to me, thanks a lot...
Last edited on
Topic archived. No new replies allowed.