Ints and Doubles doing division

2019-02-24 04:00发布

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?

5条回答
Emotional °昔
2楼-- · 2019-02-24 04:22

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

查看更多
smile是对你的礼貌
3楼-- · 2019-02-24 04:26

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.

查看更多
劳资没心,怎么记你
4楼-- · 2019-02-24 04:28

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.

查看更多
我想做一个坏孩纸
5楼-- · 2019-02-24 04:36

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.

查看更多
唯我独甜
6楼-- · 2019-02-24 04:38

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

查看更多
登录 后发表回答