When dividing numbers, the fractional part disappears

I divide two numbers by each other, for example 1 / 2 and expect to get 0.5 as a result, since I assign the result to a floating-point variable, but I get 0. Here is the code:

#include <iostream>

int main()
{
    double d = 1 / 2;
    std::cout << d << "\n";    
}
0

What could be the problem?

 16
Author: αλεχολυτ, 2017-10-04

1 answers

The fact is that in C++, as well as in C, C#, Java and many other languages, dividing integers gives only the same result, i.e. the fractional part is simply discarded.

The language standard literally says so [expl.mul]:

For integral operands the / operator yields the algebraic quotient with any fractional part discarded;

This behavior is primarily due to performance, since integer arithmetic is usually faster than floating-point arithmetic.

The fact that the result of dividing integers is assigned to a floating-point variable does not affect the division itself, since the assignment is performed after the fact of division. And we just initialize the real variable d with the integer value 0, which will not give us anything with a non-zero fractional part, for example, the expected 0.5.

To still achieve the desired result, you need to produce real division. To do this, it is enough to cast at least one of the operands to a real type. There are many ways to do this. If a constant is used, it is enough to add a period at the end of it, for example:

double d = 1 / 2.;

Or

double d = 1. / 2;

This looks minimalistic, but sometimes it's a bit strange, because in mathematics, such a notation is not used. For more clarity, we should add .0, we get:

double d = 1.0 / 2;

If instead of an explicit numeric literal if you use a named integer variable, or a function that returns an integer type, then adding a dot with a zero can no longer solve the problem, and you need to perform a different type conversion, i.e. do static_cast:

int one = 1;
int two() { return 2; }
double d = static_cast<double>(one) / two();

But you can also use multiplication (or division) of any operand by 1.0, which also converts the result, which will act as an operand of the subsequent division, to the real type:

double d = (one * 1.0) / two();

An alternative option is to add (or subtract) real zero:

double d = (one + 0.0) / two();

However, the option with static_cast will be more correct, since such transformations are always easier to find in the program text than ordinary floating constants.

And of course, if we are talking about variables or functions, you can simply change their type:

double one = 1;
double two() { return 2; }
double d = one / two();

In such a situation, we must not forget that the use of one and two in other contexts can also give different results than before. Therefore, the task is still better localize, and do not do everything completely in a real-type program, if this is required only in some special cases.

 14
Author: αλεχολυτ, 2017-10-04 21:16:56