Print decimals in c ++

2

The question is basic.

I have the following code:

#include <iostream>
#include <iomanip>

int main()
{
    double resp = 0.8912637126836812;
    resp = 5/2;
    std::cout << std::fixed << std::setprecision(4) << 5/2+20%6 << " || resp:" << resp;
    return 0;
}

As I get out, I get it.

4 || resp:2.0000

Why do not I print in the first operation the 4.5 and in the second the 2.5 that corresponds?

If I print the original value with which I initialized the variable, I will print it without problem.

Why?

    
asked by Dilakv 13.04.2018 в 06:29
source

4 answers

3
  

Why do not you print the 4.5 on the first operation and the 2.5 on the second one?

Because setprecision only works with decimal types, that is, with float and double .

In your case, all the numbers involved in the operation are of int , then the result will be, yes or yes, of type int and, therefore, will not have decimals.

As you said @GusZL the solution is to get the result is decimal. However, in C ++ I am not in favor of using a conversion bareback . This is not C and in C ++ there are 4 special functions to perform conversions that are much more powerful and secure than those used in C. You can get more information on this topic in this other question .

For this case it would be worth with static_cast :

static_cast<double>(5)/2+20%6

Notice that I only force the conversion of a number instead of the result of the operation ... if I did this:

static_cast<double>(5/2+20%6)

The 5/2 operation would be performed on integer types and would return 2 instead of 2.5 . On the other hand, as soon as one of the two numbers is double , the compiler will perform a conversion of type int to double before executing the operation:

numerador decimal:   5.0/2 => 5.0/2.0 = 2.5
denominador decimal: 5/2.0 => 5.0/2.0 = 2.5
ambos tipos enteros: 5/2   =  2             -> se descartan los decimales

Another possibility is to write the numbers that directly interest in decimal notation so that your native type is double :

opción 1: 5.0/2.0
           ~~
opción 2: 5/2.0
             ~~
opción 3: 5.0/2.0
           ~~  ~~
    
answered by 13.04.2018 / 07:45
source
1

You have to cast the result to double

#include <iostream>
#include <iomanip>

int main()
{
    double resp = 0.8912637126836812;
    resp = (double) 5/2;
    std::cout << std::fixed << std::setprecision(4) << (double) 5/2+20%6 << " || resp:" << resp;
    return 0;
}

Let me know if it works for you

    
answered by 13.04.2018 в 06:44
1

I agree with some of the answers (the result should force the type to double), but in my humble opinion the solution must go through changing this:

resp = 5/2;

for this:

resp = 5.0 / 2.0;

or because of this:

resp = ((double) 5) / 2;

Why ??? Because in the previous solution it is not clear if first is converting from 5 to double and after the division by 2 or else is the other way around: we make 5/2 as integers (result 2, because it is truncated to integer) and then we convert that 2 to double.

The purists will say that looking at the precedence of operators is the issue solved, but I think it is better to leave the novice readers the clear thing.

    
answered by 13.04.2018 в 10:16
1

C ++ does not perform operations with different types, before operating it transforms the operands to a common type following the rules of C ++ standard in section §5.9.10 (the translation and highlighted by me):

  

Several binary operators that expect operators of arithmetic or enumerated type cause conversions and return types in a similar way. The purpose is to return a common type, which is also the result type . This pattern is called usual arithmetic conversions , which is defined as follows:

     
  • ...
  •   
  • 10.2 If any of the operands is of long double , the other must be converted to long double .
  •   
  • 10.3 Otherwise, if any of the operands is double , the other must be converted to double .
  •   
  • 10.4 Otherwise, if one of the operands is float , the other must be converted to float .
  •   
  • 10.5 Otherwise, the integral promotions must be applied to both operands. Then the following rules will be applied to the promoted operands:      
    • 10.5.1 If both operands have the same type, no additional conversion is required .
    •   
    • 10.5.2 Otherwise, if both operands have signed types or both types have unsigned types, the operand with the lowest rank type will be converted to the type with the highest rank.
    •   
    • 10.5.3 Otherwise, if the operand that has unsigned integer type has a range greater than or equal to the range of the type of the other operand, the operand with signed integer type must be converted to the operand type with integer type without sign.
    •   
    • 10.5.4 Otherwise, if the type of the operand with signed integer type can represent all the values of the type of the entire inoperative operand, the pounder with unsigned integer type must be converted to the type with the operand with type whole with a sign.
    •   
    • 10.5.5 Otherwise, both operands must be converted to an unsigned integer type corresponding to the type of the entire operand without a sign.
    •   
  •   

In all your operations you are using literals of type int so the result of the operation will also be of type int :

5/2 <-- 2 es int   5/2+20%6
^                  ^ ^ ^  ^
|                  | | |  |
\_ 5 es int        | | |  \_ 6 es int
                   | | \_ 20 es int
                   | \_ 2 es int
                   \_ 5 es int
  

Why do not I print in the first operation the 4.5 and in the second the 2.5 that corresponds?

As we have already seen, the operation 5/2 is of type int , so it makes a whole division whose result is 2 , that when saving in a double remains in 2.0000 .

We have also seen that the operation 5/2+20%6 , which by operator preference is equivalent to (5 / 2) + (20 % 6) is of type int , with 2 the first result and 2 the second, therefore the operation 2 + 2 is also integer type and results in 4 .

Solution.

As we have seen in §5.9.10 of the standard, if at least one of the operands is of double , all the operands will be automatically transformed to double and the operation will return a double ; the simplest thing for this is to use a literal double adding a point ( . ) to the number:

int main()
{
    double resp = 0.8912637126836812;
    resp = 5./2.;
//          ~  ~ <-- ahora 5 y 2 son de tipo double
    std::cout << std::fixed << std::setprecision(4) << 5./2.+20%6 << " || resp:" << resp;
//                   ahora 5 y 2 son de tipo double --> ~  ~
    return 0;
}

This change causes the entire expression to be of type double and results in:

4.5000 || resp:2.5000
    
answered by 16.04.2018 в 08:06