Для этого блока кода:
int num = 5;
int denom = 7;
double d = num / denom;
значение d
есть 0.0
. Его можно заставить работать, приведя:
double d = ((double) num) / denom;
Но есть ли другой способ получить правильный double
результат? Я не люблю кастовать примитивов, кто знает, что может случиться.
java
casting
integer-division
walnutmon
источник
источник
Ответы:
Это позволяет избежать броска. Но вы обнаружите, что приведенные преобразования четко определены. Вам не нужно угадывать, просто проверьте JLS . int to double - расширяющееся преобразование. Из §5.1.2 :
5 можно выразить ровно как двойной.
источник
1.0
все равно меняет тип результата, просто по-другому. «Мне кажется, грязный код» не объясняет, в каких сценариях вы считаете, что умножение на1.0
самом деле лучше (или почему это может быть).(double)num
каким-то образом меняетсяnum
. Это не - это создает временную двойную для контекста утверждения.Что не так с примитивами?
Если по какой-то причине вы не хотите снимать, вы можете сделать
источник
double d = num * 1D / denom;
Почему у вас иррациональный страх кастовать примитивов? Ничего плохого не случится , когда вы приводите
int
кdouble
. Если вы просто не знаете, как это работает, посмотрите это в Спецификации языка Java . Приведениеint
кdouble
является расширяющимся примитивным обращением .Вы можете избавиться от лишней пары скобок, приведя знаменатель вместо числителя:
источник
double d = (double) num / denom;
... (ОК, это зависит от приоритета)Если вы измените тип единицы, то переменные, которые вы должны помнить, снова пробьют двойное число, если ваша формула изменится, потому что, если эта переменная перестанет быть частью вычисления, результат испортится. Я привожу привычку читать внутри расчета и добавляю комментарий рядом с ним.
Обратите внимание, что приведение результата не сделает этого
источник
Приведите одно из целых чисел / оба целых числа к числу с плавающей запятой, чтобы заставить операцию выполняться с помощью математической операции с плавающей запятой. В противном случае целое число Math всегда предпочтительнее. Так:
Обратите внимание, что приведение результата не сделает этого. Потому что первое деление выполняется согласно правилу приоритета.
Я не думаю, что есть какая-то проблема с кастингом, о котором вы думаете.
источник
Типовое литье - единственный путь
Произведение
double
из целочисленного деления - нет другого пути без приведения (возможно, вы не будете делать это явно, но это произойдет).Теперь, есть несколько способов , которыми мы можем попытаться получить точное
double
значение (гдеnum
иdenom
являютсяint
типом, и, конечно , с литьем ) -с явным приведением:
double d = (double) num / denom;
double d = ((double) num) / denom;
double d = num / (double) denom;
double d = (double) num / (double) denom;
но нет
double d = (double) (num / denom);
с неявным приведением:
double d = num * 1.0 / denom;
double d = num / 1d / denom;
double d = ( num + 0.0 ) / denom;
double d = num; d /= denom;
но не
double d = num / denom * 1.0;
и не
double d = 0.0 + ( num / denom );
источник
использовать что-то вроде:
(1d приведен к удвоению)
источник
Вы можете рассмотреть обертывание операций. Например:
Это позволяет вам посмотреть (только один раз), выполняет ли актерство именно то, что вы хотите. Этот метод также может быть проверен, чтобы убедиться, что он продолжает делать то, что вы хотите. Также не имеет значения, какой трюк вы используете, чтобы вызвать разделение (вы можете использовать любой из ответов здесь), если это приводит к правильному результату. Везде, где вам нужно разделить два целых числа, теперь вы можете просто позвонить
Utils::divide
и поверить, что это правильно.источник
просто используйте это.
источник
Лучший способ сделать это
источник