306

For this code block:

int num = 5;
int denom = 7;
double d = num / denom;

the value of d is 0.0. It can be forced to work by casting:

double d = ((double) num) / denom;

But is there another way to get the correct double result? I don't like casting primitives, who knows what may happen.

Tom
  • 16,842
  • 17
  • 45
  • 54
walnutmon
  • 5,873
  • 7
  • 42
  • 57
  • 14
    casting an 'int' to a double is safe, you will always get the same value without loss of precision. – Peter Lawrey Jun 30 '10 at 06:41
  • 1
    I would like to know if the following are the correct steps taken by the compiler for the division: 1) cast num to float 2) cast denom to float as well 2) divide num by denom. Please let me know if I'm incorrect. – mannyee Nov 21 '14 at 02:59

11 Answers11

191
double num = 5;

That avoids a cast. But you'll find that the cast conversions are well-defined. You don't have to guess, just check the JLS. int to double is a widening conversion. From §5.1.2:

Widening primitive conversions do not lose information about the overall magnitude of a numeric value.

[...]

Conversion of an int or a long value to float, or of a long value to double, may result in loss of precision-that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).

5 can be expressed exactly as a double.

Mindwin Remember Monica
  • 1,469
  • 2
  • 20
  • 35
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • 74
    +1. Stop being scared of casting. Learn how it works. It's all well-defined. – Mark Peters Jun 29 '10 at 21:03
  • This may not work if for some reason you should keep num beeing an integer. I think that the *1.0 solution its more flexible. – Rudolf Real Aug 20 '12 at 03:15
  • 1
    @FabricioPH This works in every situation, and identically to the *1.0 solution. – Vitruvie Feb 23 '14 at 07:55
  • 3
    @Saposhiente It goes beyond working or not. Changing the type of a variable seems dirty code to me. If you have something that MUST BE an integer and you change the representation for a float just to be able to perform the math operation, you may be risking yourself. Also in some context reading the variable as an integer makes code easier to understand. – Rudolf Real Mar 01 '14 at 15:48
  • 2
    @FabricioPH, multiplying by `1.0` still changes the type of the result, just in a different way. 'Seems dirty code to me' does not explain in what scenario(s) you believe multiplying by `1.0` is actually better (or why that might be). – Matthew Flaschen Mar 03 '14 at 04:23
  • @Matthew Flaschen In fact I did. Please read again my last comment. – Rudolf Real Mar 04 '14 at 14:08
  • 5
    @FabricioPH You and the OP seem to be labouring under the false belief (where you say "Changing the type of the variable") that doing `(double)num` somehow changes `num`. It doesn't - it creates a temporary double for the context of the statement. – Paul Tomblin Mar 27 '15 at 18:33
  • 1
    @PaulTomblin When you say `double num = 5;`, as stated in this answer, it means the variable has type double, not int. That is what FabricioPH is complaining about, not about any cast. – fishinear Dec 20 '16 at 12:39
125

What's wrong with casting primitives?

If you don't want to cast for some reason, you could do

double d = num * 1.0 / denom;
Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
89

I don't like casting primitives, who knows what may happen.

Why do you have an irrational fear of casting primitives? Nothing bad will happen when you cast an int to a double. If you're just not sure of how it works, look it up in the Java Language Specification. Casting an int to double is a widening primitive conversion.

You can get rid of the extra pair of parentheses by casting the denominator instead of the numerator:

double d = num / (double) denom;
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Jesper
  • 202,709
  • 46
  • 318
  • 350
34

If you change the type of one the variables you have to remember to sneak in a double again if your formula changes, because if this variable stops being part of the calculation the result is messed up. I make a habit of casting within the calculation, and add a comment next to it.

double d = 5 / (double) 20; //cast to double, to do floating point calculations

Note that casting the result won't do it

double d = (double)(5 / 20); //produces 0.0
alianos-
  • 886
  • 10
  • 21
26

Type Casting Is The Only Way

May be you will not do it explicitly but it will happen.

Now, there are several ways we can try to get precise double value (where num and denom are int type, and of-course with casting)-

  1. with explicit casting:
  • double d = (double) num / denom;
  • double d = ((double) num) / denom;
  • double d = num / (double) denom;
  • double d = (double) num / (double) denom;

but not double d = (double) (num / denom);

  1. with implicit casting:
  • double d = num * 1.0 / denom;
  • double d = num / 1d / denom;
  • double d = ( num + 0.0 ) / denom;
  • double d = num; d /= denom;

but not double d = num / denom * 1.0;
and not double d = 0.0 + ( num / denom );


Now if you are asking- Which one is better? explicit? or implicit?

Well, lets not follow a straight answer here. Simply remember- We programmers don't like surprises or magics in a source. And we really hate Easter Eggs.

Also, an extra operation will definitely not make your code more efficient. Right?

Minhas Kamal
  • 20,752
  • 7
  • 62
  • 64
22

Cast one of the integers/both of the integer to float to force the operation to be done with floating point Math. Otherwise integer Math is always preferred. So:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

Note that casting the result won't do it. Because first division is done as per precedence rule.

double d = (double)(5 / 20); //produces 0.0

I do not think there is any problem with casting as such you are thinking about.

Nikhil Kumar
  • 2,618
  • 3
  • 21
  • 24
2

use something like:

double step = 1d / 5;

(1d is a cast to double)

ungalcrys
  • 5,242
  • 2
  • 39
  • 23
2

Best way to do this is

int i = 3;
Double d = i * 1.0;

d is 3.0 now.
Alp Altunel
  • 3,324
  • 1
  • 26
  • 27
0

You might consider wrapping the operations. For example:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

This allows you to look up (just once) whether the cast does exactly what you want. This method could also be subject to tests, to ensure that it continues to do what you want. It also doesn't matter what trick you use to cause the division (you could use any of the answers here), as long as it results in the correct result. Anywhere you need to divide two integers, you can now just call Utils::divide and trust that it does the right thing.

Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
0

just use this.

int fxd=1;
double percent= (double)(fxd*40)/100;
FelixSFD
  • 6,052
  • 10
  • 43
  • 117
0

Just add "D".

int i = 6;
double d = i / 2D; // This will divide bei double.
System.out.println(d); // This will print a double. = 3D
Ricardo
  • 91
  • 5
  • A fractional suffix `.0` is generally clearer for the humans. `d` is the next best option. I would consider `D` to be harmful as it looks too much like a digit to be adjacent to digits. – AndrewF Aug 15 '20 at 04:07