135

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?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Jahoe
  • 1,666
  • 2
  • 12
  • 27
  • Possible duplicate of [Division result is always zero](https://stackoverflow.com/questions/2345902/division-result-is-always-zero) – phuclv Sep 09 '18 at 04:51

10 Answers10

193

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;
Chad La Guardia
  • 5,088
  • 4
  • 24
  • 35
  • 10
    I would prefer to explicitly convert both `a` and `b` to `double` simply for clarity, but it really doesn't matter. – John Dibling Sep 27 '11 at 15:31
  • 37
    Since the question is tagged C++ I would prefer to see static_cast<> rather than a C cast. – Martin York Sep 27 '11 at 15:41
  • 19
    Personally, I feel that the C style casts are clearer (casting in most other common languages is done in the C style way). `static_cast<>` always seemed long winded to me. In the case of primitives, there is not really any danger of getting `static_cast<>` and `reinterpret_cast<>` mixed up. – Chad La Guardia Sep 27 '11 at 15:47
  • 8
    @Tux-D: For arithmetic casts? I would prefer to avoid `static_cast` in this case and use C-style cast instead. There's no benefit in using C++-style casts here and they clutter the code a lot more than C-style casts. Arithmetic cast is exactly the context where C-style casts are perfectly appropriate and actually more appropriate than other casts. – AnT stands with Russia Sep 27 '11 at 16:14
  • 23
    Sometimes you can outwit the "no C-style-cast" folks by writing `double(b)`. They don't always realise that it's a conversion, since it looks the same as an explicit constructor call. – Steve Jessop Sep 27 '11 at 16:26
  • casting one `int` to double works fine. But why? I confused about user defined type that. when we overload operator then left variable(object) decide to call which class operator. `INT obj; obj/3;` here / called for obj class. not for 3. – Asif Mushtaq Jan 16 '16 at 15:38
15

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.

nplatis
  • 432
  • 2
  • 8
14

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.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 3
    The one exception I can think of is choosing a function overload when taking a pointer - the value of `&funcname` depends what type you cast it to. – Steve Jessop Sep 27 '11 at 15:44
  • 2
    @Steve Jessop That's the only exception I can think of as well. (But given the size and complexity of the standard, I wouldn't like to swear that I haven't missed any.) – James Kanze Sep 27 '11 at 16:01
9

In C++ language the result of the subexpresison 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 contains of an independent subexpression a / b, which is interpreted independently from anything outside that subexpression. 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 juts 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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
8

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

Alok Save
  • 202,538
  • 53
  • 430
  • 533
7

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).

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
5

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.

Vicky
  • 12,934
  • 4
  • 46
  • 54
3

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.

matthewdunnam
  • 1,656
  • 2
  • 19
  • 34
  • This question is tagged [C++], and the C++ Standard dictates exactly how this works. Not sure what you mean by "language specific" and it's certainly not compiler-specific, assuming no compiler extenstions are engaged. – John Dibling Sep 27 '11 at 15:32
  • Also it's incorrect to say that "double var = integer result which casts the double var down to int". The double isn't cast to an int. The int result is converted to a double. – John Dibling Sep 27 '11 at 15:35
  • I was allowing for the possibility of compiler extensions (I've actually had this issue once where my environment was "mis-casting" the results and I couldn't figure out why). And the result is language specific as in some languages don't follow the same casting rules. I didn't consider that it was a C++ specific tag. You're right about the "double var = integer result" comment. Edited to reflect that. Thank you! – matthewdunnam Sep 27 '11 at 20:18
2

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.

Adola
  • 337
  • 1
  • 16
1

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).

TheArchitect
  • 1,160
  • 4
  • 15
  • 26