views:

73

answers:

5

Short version: Why don't I have to coerce 60, and int, into a double, so that I can use division with another double if I DO care about the fractional part?

Long version: my boss called me out on a line of code. I tested it and it is working perfectly fine, but he thinks I have a bug waiting to happen.

int durationinseconds = 61;  // This is actually filled from a double.tryparse 
                             // from a string value out of an xml doc.
int durationinminutes = (int)Math.Ceiling((double)durationinseconds / 60);

My code is supposed to get the # of seconds from the XML doc, then figure out the # of minutes, always rounding up. 60 seconds = 1 minute, 61 seconds = 2 minutes, etc.

I've tested my code, but he INSISTS that the "/ 60" part should be "/ 60.0".

I've tested my code with 0, 1, 2, 59, 60, 61, 119, 120, 121, 599, 600, 601, etc, and it always works out correctly.

Before I go defend myself to him, I mostly understand why he thinks that I need to coerce 60 to be a decimal, because he thinks that if I use an int value then a double / int will result in an integer value, effectively dropping the fractional part.

However, that is not happening here, and I can't exactly explain why. So, that is my question: WHY don't I have to use 60.0 when dividing a double if I want to use the fractional part?

+3  A: 

Dividing double by an integer will result in double.

No need for 60.0. You can use 60.0 and drop the double cast, instead. No need to use both. It is completely redundant.

Pavel Radzivilovsky
I'd upvote your answer but something about my new job's firewall is making it impossible to log in with openid. I WILL upvote it at some point in the future when I get onto Stackoverflow from a computer with less restrictions, I promise. Thanks for the answer.
Matt
+1  A: 

Converting your durationInSeconds is enough. It will produce a double, and will round up to 2.

Mike M.
I'd upvote your answer but something about my new job's firewall is making it impossible to log in with openid. I WILL upvote it at some point in the future when I get onto Stackoverflow from a computer with less restrictions, I promise. Thanks for the answer.
Matt
+3  A: 

You are right. The int 60 is promoted to double automatically. Writing 60.0 is correct, but redundant.

C# language specification, "7.2.6.2 Binary numeric promotions": http://msdn.microsoft.com/en-us/library/aa691330.aspx

Tim Robinson
I'd upvote your answer but something about my new job's firewall is making it impossible to log in with openid. I WILL upvote it at some point in the future when I get onto Stackoverflow from a computer with less restrictions, I promise. Thanks for the answer.
Matt
+8  A: 

Here are the relevant division operators:

public static double operator /(double x, double y)
public static int operator /(int x, int y)

There is an implicit conversion from int to double, but not the other way round... so if you divide an int by an int, you'll use the integer form... but if either operand is a double, it will use the double form.

There's no need to make both operands double - but your code would be at least shorter if you made the divisor operand a double instead of casting:

int durationInMinutes = (int) Math.Ceiling(durationInSeconds / 60.0);

Personally I find that easier to read... but it's a personal choice.

If you want to prove to your boss that it's really doing floating point division, use iladsm or reflector (in IL mode) on your code - it will show an ldc.r8 instruction for the constant, which means a double value.

Jon Skeet
Succinct and perfectly made to show him I'm not an idiot. To be clear, I don't want to run to him and say "na na I'm right!" This is my 2nd week here, and I want him to think I'm not an idiot. I'm well aware of problems that can arise from implicit casting and division with losing precision, but I also tested this fully before I pushed it live to make sure I wasn't making a dumb mistake.Thanks again, Jon. I'd upvote your answer and several others, but something about my new job's firewall is making it impossible to log in with openid.
Matt
Would it not also be correct to use `60D` in place of `60.0`? I am not sure of the readability/correctness of that, but have seen it a few times.
JYelton
+1  A: 

You can't divide a double by an integer, so the compiler will cast the integer to a double.

So, the expressions (double)durationinseconds / 60 and (double)durationinseconds / 60.0 will result in identical code being created.

I prefer using 60.0 in this case just to make it more visible what the code is actually doing.

Guffa
I'd upvote your answer but something about my new job's firewall is making it impossible to log in with openid. I WILL upvote it at some point in the future when I get onto Stackoverflow from a computer with less restrictions, I promise. Thanks for the answer.
Matt