The problem lies in the type of variable used. People are used to make comparisons to use:
int valor;
std::cin >> valor;
if( valor < 10 )
// ...
But with floating-point numbers you have to be more careful and the reason is that both float
and double
do not have full precision, but have a series of trash digits. In the case of float
, only the first 6 digits are representative, while in the case of double
we can trust the first 12.
That there are garbage digits implies that there are several binary representations that give us, effectively, the same number. Thus, for a type float
, it would be understood that both numbers should be the same:
6 digitos | basura
1,00000 01
1,00000 09
And yet the comparison operator would tell us that the values are different. That is, when comparing variables in floating point we have to make relative comparisons. That is, we must establish a margin of error, so we understand that two variables are equal if that margin of error is not exceeded.
For example, to compare if the value of a float
equals 10 we should do something like this:
float valor;
std::cin >> valor;
if( std::abs(valor - 10) < 1e-6 )
// ^^^^ Margen de error
{
// ...
}
This feature of floating point coding also affects operators less than , greater than , less than or equal , greater or equal and different . Special attention must be paid to this aspect, since if the stored value is close enough (they differ only in junk digits) from the reference value, the result of the comparison may not be satisfactory. Think, for example, of the values that I have put before:
6 digitos | basura
1,00000 01
1,00000 09
An operation of greater or equal should result in true
and, nevertheless, it will return false
since in first digit it is, really, smaller than the second one. Likewise, the operator different !=
will return true
.
All this said, the exercise should look like this
#include <iostream>
using namespace std;
int main() {
float consumoGeneral = 0;
float consumo = 0;
float const error = 1e-5;
cout << "\t\tEficiencia Energetica" << endl;
cout << endl << endl;
cout << "Para determinar la eficiencia energetica \ningrese el Consumo "
"General (en kW): ";
cin >> consumoGeneral;
cout << endl;
cout << "Ahora ingrese el consumo a comparar: ";
cin >> consumo;
cout << endl;
if( consumoGeneral + error < consumo )
std:cout << "ALTO CONSUMO DE ENERGIA";
else if( consumoGeneral * 0.8 - error > consumo )
std::cout << "CONSUMO MEDIO";
else
cout << "CONSUMO BAJO";
cin.get();
return 0;
}
In the first comparison, to consumoGeneral
we add a margin of error. What we do is assume that consumo==consumoGeneral
while the difference between both is less than error
, to avoid uncertainty, we add the margin of error to consumption.
In the comparison of the average consumption something similar happens ... only now the margin of error remains. Now it is subtracted because the operator we replace is greater or equal , and it is precisely that equal that forces us to subtract the margin of error. What we do is include the (consumoGeneral-error,consumoGeneral)
range in the valid set of values.