Doubt about the behavior of an integer variable

5

I have made the following program that calculates the inheritance based on the number of children:

#include <iostream>

using namespace std;

int leer_datoi()
{
    int dato;

    cin >> dato;

    return dato;    
}

double leer_datod()
{
    double dato;

    cin >> dato;

    return dato;
}

void calcular_herencia()
{
    double herencia, mayor;
    int num_hijos;

    do{
    cout << "Ingrese el importe de la herencia:\t";
    herencia=leer_dato_d();
    cout << "\n";

    if(herencia<=0)
        cout << "ERROR. Ingrese una cantidad positiva\n" << endl;
   } while(herencia<=0);

   do{
      cout << "Ingrese la cantidad de hijos:\t\t";
      num_hijos=leer_dato_i();
      cout << "\n";

      if(num_hijos<=0)
        cout << "ERROR. Ingrese una cantidad positiva\n" << endl;
  } while(num_hijos<=0);

    if(num_hijos<=4)
    {
        herencia=herencia/num_hijos;
        cout << "La herencia para cada hijo es:\t\t" << herencia << "\n" << endl;
    }
    else
    {
        mayor=herencia/2;
        herencia=mayor/(num_hijos-1);
        cout << "La herencia para el hijo mayor es:\t" << mayor << "\n" << endl;
        cout << "La herencia para el resto de hijos es:\t" <<  herencia << "\n" << endl;
    }
}

int main()
{
    calcular_herencia();    

    return 0;
}

I tried it and it works normal. Then, out of curiosity I put a non-integer value when entering the number of children (let's say 4.5) and likewise the program worked, which seems odd to me since the variable num_hijos is of integer type.

My question is:

Why is this?

    
asked by Xam 30.10.2017 в 23:57
source

3 answers

5

When the program encounters this:

int dato;
cin >> dato;

Try reading an integer from the standard input. If the first character found is a numeric digit or the sign ( + or - ), the stream will understand that it can start to extract an integer. When it ends? As you are reading an integer it will end when you can not extract more digits, which happens, depending on your case, when it meets the point. At that moment, stop reading and return in dato the number read until that moment.

That is, before an input 4.5 , in dato a 4 is stored and in the input buffer the residual .5 remains. You can check that this is true with the following example:

int main()
{
  std::string cadena;
  int variable;

  std::cin >> variable >> cadena;
  std::cout << variable << '\n' << cadena << '\n';
}

Before a type entry 4.5 the program prints the following:

4
.5

So, as you can see, the program does not do any magic but just gives you what you ask.

We would have a different situation if the conversion were made once the data was read. For example, imagine that instead of reading an integer, read double and then try to store that number in an integer. Something like this:

double temporal;

std::cin >> temporal;
int dato = static_cast<int>(temporal);

In this case, cin will read the full number 4.5 and store it in temporal . The conversion to integer will cause a truncation of decimals, so the decimal part ( .5 ) will be lost and in dato the whole part will be finally stored ( 4 ).

Where is the difference in both cases? The result stored in dato does not change, it is the same in both cases, however in this second example the input buffer is clean, without waste.

If we modify the example a bit:

int main()
{
  int v1, v2;

  std::cin >> v1 >> v2;
  std::cout << v1 << '\n' << v2 << '\n';
}

And you enter, for example, 4.5 6 the program will print the following:

4
0

Where does that 0 come from? What happens is that after reading the first integer in the input buffer the following residual remains: .5 6 . That initial point prevents you from correctly reading a second integer. When the reading error occurs, the error flags of cin are activated and the stream is blocked until these flags are restarted.

This example shows how important it is to clean the input buffer before reading:

#include <iostream>
#include <limits>

int main()
{
  int v1, v2;

  if( !(std::cin >> v1) )
    std::cin.clear();

  std::cin.ignore(std::numeric_limits<int>::max(),'\n');

  std::cin >> v2;

  std::cout << v1 << '\n' << v2;
}

Where:

  • The clear method cleans the stream error flags. This action is only executed when the reading of the first integer fails (for example if you enter a character).
  • The ignore method allows you to discard characters from the stream . In this case all characters that are found until the first line break will be discarded.
  • numeric_limits is a class that allows you to obtain the limit values for each type of data (remember that the ranges are usually dependent on the machine). In this case it gets the highest number that can be stored in a signed integer.
answered by 31.10.2017 / 07:48
source
3

The program when doing the input data capture through cin will effectively process the data as double-precision type. When the assignment to the local variable dato is made in the function leer_datoi , the fractional part will be truncated and only the whole part will be taken.

You can do the following test:

int leer_datoi() 
{
   int dato;

   cin >> dato;
   cout << dato;

   return dato;    
}

You should see here a 4 as a screen output

    
answered by 31.10.2017 в 01:50
0

Integer variables keep integers. If you enter any variable with a comma, save the integer. This serves in many cases to break down whole ... Ex: 17022017 is a date type ddmmyyyy, if we want to save the day we define: Int day = 17022017/1000000 What results in 17.022017 ... but when only the whole is saved then day == 17

    
answered by 31.10.2017 в 01:53