Ints and Doubles занимаются делением - PullRequest
4 голосов
/ 07 июля 2010

Короткая версия: Почему мне не нужно приводить 60 и целое число к двойному, чтобы я мог использовать деление с другим двойным, если мне НЕ интересна дробная часть?

Длинная версия: мой босс вызвал меня в строке кода. Я проверил его, и он работает отлично, но он думает, что у меня ошибка, ожидающая появления.

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

Мой код должен получить количество секунд из документа XML, а затем вычислить количество минут, всегда округляя. 60 секунд = 1 минута, 61 секунда = 2 минуты и т. Д.

Я проверил свой код, но он НАСТАИВАЕТ, что часть "/ 60" должна быть "/ 60.0".

Я проверил свой код с 0, 1, 2, 59, 60, 61, 119, 120, 121, 599, 600, 601 и т. Д., И он всегда работает правильно.

Прежде чем я пойду защищаться от него, я в основном понимаю, почему он думает, что мне нужно привести 60 к десятичному знаку, потому что он думает, что если я использую значение int, то double / int приведет к целочисленному значению, эффективно отбрасывая дробную часть.

Однако этого здесь не происходит, и я не могу точно объяснить, почему. Итак, вот мой вопрос: ПОЧЕМУ мне не нужно использовать 60,0 при делении двойного, если я хочу использовать дробную часть?

Ответы [ 5 ]

10 голосов
/ 07 июля 2010

Вот соответствующие операторы деления:

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

Существует неявное преобразование из int в double, но не наоборот ... так что если вы разделите int на int, вы будете использовать целочисленную форму ... но если любой из операндов является двойным, он будет использовать двойную форму.

Нет необходимости делать оба операнда double - но ваш код будет по крайней мере короче, если вы сделаете операнд-делитель двойным вместо приведения:

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

Лично мне легче читать ... но это личный выбор.

Если вы хотите доказать своему боссу, что он действительно выполняет деление с плавающей запятой, используйте iladsm или отражатель (в режиме IL) в вашем коде - он покажет инструкцию ldc.r8 для постоянной что означает double значение.

3 голосов
/ 07 июля 2010

Вы правы. Int 60 автоматически повышается до double. Запись 60.0 правильная, но избыточная.

Спецификация языка C #, "7.2.6.2 Двоичные числовые продвижения": http://msdn.microsoft.com/en-us/library/aa691330.aspx

3 голосов
/ 07 июля 2010

Деление double на целое число приведет к двойному.

Нет необходимости в 60,0. Вместо этого вы можете использовать 60.0 и сбросить двойное приведение. Не нужно использовать оба. Это полностью избыточно.

1 голос
/ 07 июля 2010

Вы не можете разделить double на целое число, поэтому компилятор преобразует это число в double.

Итак, выражения (double)durationinseconds / 60 и (double)durationinseconds / 60.0 приведут к созданию идентичного кода.

Я предпочитаю использовать 60.0 в этом случае, просто чтобы сделать его более наглядным, что на самом деле делает код.

1 голос
/ 07 июля 2010

Преобразование вашей продолжительности в секундах достаточно.Это даст двойное число и округлит до 2.

...