#java
#java
Вопрос:
Я хочу вычесть одно целое число из другого, и результат должен быть равен 0. Таким образом, 2 минус 4 должно равняться 0. Я мог бы просто сделать
int result = x - y;
if (result < 0) result = 0;
Но есть ли более элегантный способ?
Ответ №1:
int result = Math.max(0, x - y);
Ответ №2:
В то время как многие люди спешат с Math.max(...)
решениями, я хотел бы предложить простой оператор if.
if (y > x) {
result = 0;
} else {
result = x - y;
}
Гарантируется, что результат всегда возвращается равным 0, для этого не требуется вызывать дополнительный фрейм стека (для этого потребовался бы ввод математической статической функции), и это предотвращает переполнение.
В редких случаях, когда X близко к минимальному значению int, а y достаточно велико, вычисление (x-y) приведет к неполному потоку. Результат был бы «слишком большим» отрицательного числа, чтобы поместиться в пространстве int, и, следовательно, превратился бы в бессмысленный (и, вероятно, положительный) ответ.
Заставляя оператор if гарантировать отсутствие переполнения, это решение также более правильное, чем Math.max(...)
решения. Однако большинству людей все равно, потому что они редко имеют дело с числами, которые приближаются к тому, чтобы вызывать переполнения и недопотоки.
Комментарии:
1. На самом деле, это менее правильное решение проблемы, как указано в OP. Кроме того, есть хороший шанс, что Math.max достаточно мал, чтобы JIT-компилятор встроил его.
2. @Stephen, операционная система подвержена переполнению так же, как и решение Math.max(). Это связано с тем, что вы не можете гарантировать от недостаточного потока после вычитания, вы должны проверить это перед вычитанием. Пусть X = целое число. MIN_INT и Y = 8, вы получите недостаточный поток (вероятно, возвращая положительное число, которое затем вы будете рассматривать как ответ).
3. Я это знаю. Но вопрос OP … как указано … требуется, чтобы это произошло. Здесь четко сказано «вычесть два числа», а не «найти разницу между двумя числами». Вы изменили проблему. Это может быть тем, что в конечном итоге нужно OP … или нет.
Ответ №3:
Используйте тернарный оператор ?:
int result = (x - y) > 0 ? (x - y) : 0;
Комментарии:
1. Это условный оператор … это просто троичный оператор. Также это бесполезно, если x или y — вызов функции.
2. @trinithis почему вы говорите, что это нехорошо, если второй и / или третий операнды являются функциональными вызовами?
3. @edalorzo: Поскольку функции будут выполняться дважды, что вряд ли желательно и, возможно, вызовет значительно плохой побочный эффект.
4. @trinth: Это условный оператор, но почему бы и нет? По крайней мере, это позволяет избежать ошибки вашего решения, и это может выглядеть более элегантно. Однако: в Java x и y не могут быть вызовами функций.
5. @trinth они будут выполняться дважды, только если условие в этом случае оценивается как true. В любом случае я понимаю вашу точку зрения и согласен, хотя в данном случае это не имеет значения, поскольку ни один из операндов не использует вызовы metod. Кстати, JLS также ссылается на этот оператор как на троичный условный оператор (стр. 526).