Деление целых чисел в Java [дубликат]
этот вопрос уже есть ответ здесь:
почему результат 1/3 == 0?
13 ответов
Это базовый вопрос, но я не могу найти ответ. Я изучил арифметику с плавающей запятой и несколько других тем, но ничего, казалось, не касалось этого. Я уверен, что просто ошибаюсь терминология.
В принципе, я хочу взять две величины - завершенные и полные - и разделить их, чтобы придумать процент (от того, сколько было завершено). Количество - это longы. Вот настройки:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
Я попытался переназначить результат на двойной-он печатает 0.0. Где я ошибаюсь?
кстати, следующий шаг-умножить этот результат на 100, что я предполагаю, должно быть легко, как только это небольшое препятствие будет шагнуто свыше.
кстати, не домашнее задание здесь просто старая тупость (и, возможно, слишком много кодирования сегодня).
7 ответов:
преобразование выход слишком поздно; расчет уже состоялся в целочисленной арифметике. Вам нужно преобразовать входы до
double:System.out.println((double)completed/(double)total);обратите внимание, что вы на самом деле не нужно конвертировать и из них; пока один
double, другой будет неявно преобразован. Но я предпочитаю делать и то и другое, для симметрии.
вам даже не нужны двойники для этого. Просто умножьте на 100 первый а затем разделить. В противном случае результат будет меньше 1 и будет усечен до нуля, как вы видели.
edit: или если переполнение вероятно, если оно будет переполнено (т. е. дивиденд больше, чем 922337203685477581), сначала разделите делитель на 100.
преобразование
completedиtotaltodoubleили по крайней мере, бросить их вdoubleпри выполнении devision. Т. е. бросить varaibles удвоить не только результат.справедливое предупреждение, есть проблема точности с плавающей точкой при работе с
floatиdouble.
Если вы явно не приведете одно из двух значений к поплавку перед выполнением деления, то будет использоваться целочисленное деление (поэтому вы получаете 0). Вам просто нужно, чтобы один из двух операндов был значением с плавающей запятой, так что используется нормальное деление (а другое целочисленное значение автоматически превращается в float).
просто попробуй с
float completed = 50000.0f;и все будет хорошо.
In Java Integer/Integer = Integer Integer/Double = Double//Either of numerator or denominator must be floating point number 1/10 = 0 1.0/10 = 0.1 1/10.0 = 0.1просто введите cast любой из них.
как объяснить JLS, целочисленные операции довольно просты.
если целочисленный оператор, отличный от оператора сдвига, имеет хотя бы один операнд типа long, то операция выполняется с использованием 64-разрядной точности, а результат числового оператора имеет тип long. Если другой операнд не длинен, он сначала расширяется (§5.1.5), чтобы ввести long числовым продвижением (§5.6).
в противном случае операция проводится с использованием 32-разрядная точность, а результат числового оператора имеет тип int. Если какой-либо операнд не является int, он сначала расширяется до типа int с помощью числового продвижения.
поэтому, чтобы сделать его коротким, операция всегда приведет к
intза единственным исключением, что естьlongзначение в нем.int = int + int long = int + long int = short + shortобратите внимание, что приоритет оператора важен, поэтому если у вас есть
long = int * int + longthe
int * intоперация приведет кint, это было бы способствовать вlongв ходе операцииint + long
в качестве выходных результатов double вы должны привести либо завершенную переменную, либо общую переменную, либо оба удвоить при делении.
таким образом, верной реализации будет:
System.out.println((double)completed/total);
Comments