11

This behaves as wanted:

double t = r[1][0] * .5;

But this doesn't:

double t = ((1/2)*r[1][0]);

r is a 2-D Vector.

Just thought of a possibility. Is it because (1/2) is considered an int and (1/2) == 0?

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Roger Lam
  • 962
  • 2
  • 8
  • 17

6 Answers6

58

Is it because (1/2) is considered an int and (1/2) == 0?

Yes, both of those literals are of type int, therefore the result will be of type int, and that result is 0.

Instead, make one of those literals a float or double and you'll end up with the floating point result of 0.5, ie:

double t = ((1.0/2)*r[1][0]);

Because 1.0 is of type double, the int 2 will be promoted to a double and the result will be a double.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
14

Write this instead:

  double t = ((1/2.0)*r[1][0]);

1 / 2 is an integer division and the result is 0.

1 / 2.0 is a floating point division (with double values after the usual arithmetic conversions) and its result is 0.5.

ouah
  • 142,963
  • 15
  • 272
  • 331
6

Because 1/2 is int/int division. That means whatever is the result will have anything after the decimal point removed (truncated). So 1/2 = 0.5 = 0.

Normally I always write the first number in double : 1.0/2 …..

If you make the very first number a double then all remaining calculation is done in double only.

Frungi
  • 506
  • 5
  • 16
AgA
  • 2,078
  • 7
  • 33
  • 62
  • Doesn't have to be *the first number*, just one of them at least. – Marlon Mar 19 '12 at 06:36
  • Just make a habit of using first number as float then you won't run into surprises. Another good habit is to start with 1.0 * .... – AgA Mar 19 '12 at 06:44
  • 2
    Note that in `2.0 * x + (7 / 5)`, the first number is a `double` and the OP's issue is still present. – Pascal Cuoq Mar 19 '12 at 09:36
  • You're right, but this is the best we can do to minimize such issues. – AgA Mar 21 '12 at 04:08
2
double t = r[1][0] * .5;

is equivalent to:

double t = ((1/2f)*r[1][0]);

and not:

double t = ((1/2)*r[1][0]);

Due to loss of decimal part when the temporary result of 1/2 is stored in an int variable.

As a guideline whenever there is a division and there is a possibility of the answer being real number, do not use int or make one of the operands float or double or use cast.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
1

You can write 1.0/2.0 instead. 1/2 displays this behaviour because both the denominator and numerator act are of an integer type and a variable of an integer type divided by another variable of an integer type is always truncated to an integer.

Cactus Golov
  • 3,474
  • 1
  • 21
  • 41
Pawriwes
  • 283
  • 1
  • 6
  • 21
0

I cannot merit or demerit the standard of the question but this seem very critical issue to me. We assume that compiler will do the laundry for us all the time , but that is not true some times.

Is there any way to avoid this situation ?

Possibly

OR

More importantly knowing the monster (C,C++) as most of the people point out above

I would like to know if there are other ways to trace these "truncation" issues at compile time

Community
  • 1
  • 1
sakhunzai
  • 13,900
  • 23
  • 98
  • 159