Jahoe
Jahoe

Reputation: 1726

Why does dividing two int not yield the right value when assigned to double?

How come that in the following snippet

int a = 7;
int b = 3;
double c = 0;
c = a / b;

c ends up having the value 2, rather than 2.3333, as one would expect. If a and b are doubles, the answer does turn to 2.333. But surely because c already is a double it should have worked with integers?

So how come int/int=double doesn't work?

Upvotes: 141

Views: 221968

Answers (10)

AnT stands with Russia
AnT stands with Russia

Reputation: 320361

In C++, the result of the sub-expression is never affected by the surrounding context (with some rare exceptions). This is one of the principles that the language carefully follows. The expression c = a / b consists of an independent sub-expression a / b, which is interpreted independently from anything outside that sub-expression. The language does not care that you later will assign the result to a double. a / b is an integer division. Anything else does not matter. You will see this principle followed in many corners of the language specification. That's just how C++ (and C) works.

One example of an exception I mentioned above is the function pointer assignment/initialization in situations with function overloading

void foo(int);
void foo(double);

void (*p)(double) = &foo; // automatically selects `foo(fouble)`

This is one context where the left-hand side of an assignment/initialization affects the behavior of the right-hand side. (Also, reference-to-array initialization prevents array type decay, which is another example of similar behavior.) In all other cases the right-hand side completely ignores the left-hand side.

Upvotes: 9

HuskyDucky
HuskyDucky

Reputation: 1278

The important thing is one of the elements of calculation be a float-double type. Then to get a double result you need to cast this element like shown below:

c = static_cast<double>(a) / b;

or c = a / static_cast(b);

Or you can create it directly::

c = 7.0 / 3;

Note that one of elements of calculation must have the '.0' to indicate a division of a float-double type by an integer. Otherwise, despite the c variable be a double, the result will be zero too (an integer).

Upvotes: 1

Adola
Adola

Reputation: 337

For the same reasons above, you'll have to convert one of 'a' or 'b' to a double type. Another way of doing it is to use:

double c = (a+0.0)/b;

The numerator is (implicitly) converted to a double because we have added a double to it, namely 0.0.

Upvotes: 2

matthewdunnam
matthewdunnam

Reputation: 1686

This is technically a language-dependent, but almost all languages treat this subject the same. When there is a type mismatch between two data types in an expression, most languages will try to cast the data on one side of the = to match the data on the other side according to a set of predefined rules.

When dividing two numbers of the same type (integers, doubles, etc.) the result will always be of the same type (so 'int/int' will always result in int).

In this case you have double var = integer result which casts the integer result to a double after the calculation in which case the fractional data is already lost. (most languages will do this casting to prevent type inaccuracies without raising an exception or error).

If you'd like to keep the result as a double you're going to want to create a situation where you have double var = double result

The easiest way to do that is to force the expression on the right side of an equation to cast to double:

c = a/(double)b

Division between an integer and a double will result in casting the integer to the double (note that when doing maths, the compiler will often "upcast" to the most specific data type this is to prevent data loss).

After the upcast, a will wind up as a double and now you have division between two doubles. This will create the desired division and assignment.

AGAIN, please note that this is language specific (and can even be compiler specific), however almost all languages (certainly all the ones I can think of off the top of my head) treat this example identically.

Upvotes: 3

nplatis
nplatis

Reputation: 442

Here it is:

a) Dividing two ints performs integer division always. So the result of a/b in your case can only be an int.

If you want to keep a and b as ints, yet divide them fully, you must cast at least one of them to double: (double)a/b or a/(double)b or (double)a/(double)b.

b) c is a double, so it can accept an int value on assignement: the int is automatically converted to double and assigned to c.

c) Remember that on assignement, the expression to the right of = is computed first (according to rule (a) above, and without regard of the variable to the left of =) and then assigned to the variable to the left of = (according to (b) above). I believe this completes the picture.

Upvotes: 15

James Kanze
James Kanze

Reputation: 153889

With very few exceptions (I can only think of one), C++ determines the entire meaning of an expression (or sub-expression) from the expression itself. What you do with the results of the expression doesn't matter. In your case, in the expression a / b, there's not a double in sight; everything is int. So the compiler uses integer division. Only once it has the result does it consider what to do with it, and convert it to double.

Upvotes: 15

Vicky
Vicky

Reputation: 13244

The / operator can be used for integer division or floating point division. You're giving it two integer operands, so it's doing integer division and then the result is being stored in a double.

Upvotes: 5

Alok Save
Alok Save

Reputation: 206498

When you divide two integers, the result will be an integer, irrespective of the fact that you store it in a double.

Upvotes: 8

Chad La Guardia
Chad La Guardia

Reputation: 5164

This is because you are using the integer division version of operator/, which takes 2 ints and returns an int. In order to use the double version, which returns a double, at least one of the ints must be explicitly casted to a double.

c = a/(double)b;

Upvotes: 196

Fred Foo
Fred Foo

Reputation: 363467

c is a double variable, but the value being assigned to it is an int value because it results from the division of two ints, which gives you "integer division" (dropping the remainder). So what happens in the line c=a/b is

  1. a/b is evaluated, creating a temporary of type int
  2. the value of the temporary is assigned to c after conversion to type double.

The value of a/b is determined without reference to its context (assignment to double).

Upvotes: 7

Related Questions