double num = 5;
Это позволяет избежать приведения. Но вы обнаружите, что преобразования конверсий четко определены. Вам не обязательно гадать, просто проверьте JLS . int double - это расширяющееся преобразование. Из §5.1.2 :
Расширение примитивных преобразований не теряет информации об общей величине числового значения.
[... ]
Преобразование значения int или long для float или длинного значения в double может привести к потере точности, то есть результат может потерять некоторые из наименее значимых бит значения , В этом случае результирующее значение с плавающей запятой будет правильно округленной версией целочисленного значения с использованием режима IEEE 754 round-to-ближайшее (§4.2.4) .
blockquote>5 может быть выражено точно как double.
Если вы измените тип одного из переменных, которые вы должны запомнить, чтобы снова прокрасться в двойник, если ваша формула изменится, потому что если эта переменная перестает быть частью вычисления, результат будет испорчен. Я делаю привычку кастинга в вычислении и добавляю комментарий рядом с ним.
double d = 5 / (double) 20; //cast to double, to do floating point calculations
Обратите внимание, что приведение результата не будет выполнено
double d = (double)(5 / 20); //produces 0.0
Лучший способ сделать это -
int i = 3;
Double d = i * 1.0;
d is 3.0 now.
Мне не нравятся кастинговые примитивы, кто знает, что может случиться.
blockquote>Почему у вас есть иррациональный страх перед литьем примитивов? Ничего плохого не произойдет, если вы нажмете
int
наdouble
. Если вы просто не знаете, как это работает, посмотрите его в Спецификация языка Java . Отбрасываниеint
вdouble
является расширением примитивного преобразования .Вы можете избавиться от дополнительной пары круглых скобок, выставив знаменатель вместо числителя:
double d = num / (double) denom;
просто используйте это.
int fxd=1;
double percent= (double)(fxd*40)/100;
Вы можете рассмотреть возможность переноса операций. Например:
class Utils
{
public static double divide(int num, int denom) {
return ((double) num) / denom;
}
}
Это позволяет вам искать (только один раз), делает ли бросок именно то, что вы хотите. Этот метод также может быть подвергнут испытаниям, чтобы он продолжал делать то, что вы хотите. Также не имеет значения, какой трюк вы используете для деления (вы можете использовать любой из ответов здесь), если это приводит к правильному результату. В любом месте вам нужно разделить два целых числа, теперь вы можете просто вызвать Utils::divide
и верить, что он поступает правильно.
Производит 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 );
Отправляйте одно из целых чисел / оба целого числа для плавания, чтобы заставить операцию выполнить с помощью математики с плавающей запятой. Иначе целочисленная математика всегда предпочтительна. Итак:
1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;
Обратите внимание, что выполнение результата не будет выполнено. Поскольку первое деление выполняется в соответствии с правилом приоритета.
double d = (double)(5 / 20); //produces 0.0
Я не думаю, что есть какие-либо проблемы с кастингом, о котором вы думаете.
Что не так с литейными примитивами?
Если вы не хотите бросать по какой-либо причине, вы можете сделать
double d = num * 1.0 / denom;
используйте что-то вроде:
double step = 1d / 5;
(1d - это бросок, чтобы удвоить)