Есть ли какая-либо функция Java или класс util, который выполняет округление таким образом:функция (3/2) = 2?
Вопрос
Есть ли какая-нибудь Java-функция или util class
который выполняет округление таким образом: func(3/2) = 2
Math.ceil()
не помогает, хотя по названию должно было бы это сделать.Я осознаю BigDecimal
, но мне это не нужно.
Решение
Math.ceil()
всегда будет округляться в большую сторону, однако вы выполняете целочисленное деление с 3/2
.Таким образом, поскольку при целочисленном делении 3/2 = 1
(не 1.5
) потолок из 1
является 1
.
Что вам нужно было бы сделать, чтобы достичь желаемых результатов, это Math.ceil(3/2.0);
Выполнив деление на двойную сумму (2.0
), в конечном итоге вы выполняете деление с плавающей запятой вместо целочисленного деления.Таким образом 3/2.0 = 1.5
, и в ceil()
из 1.5
всегда есть 2
.
Другие советы
Немного черной магии, и вы сможете делать все это с целыми числами:
// Divide x by n rounding up
int res = (x+n-1)/n
Вы всегда можете бросить первым:
Math.ceil((double)3/2)
Чтобы преобразовать разделение пола в разделение потолка:
(numerator + denominator-1) / denominator
Чтобы преобразовать деление этажа в деление округления:
(numerator + (denominator)/2) / denominator
В Java 3/2 = 1, потому что она использует целочисленное деление.Нет никакой функции, которая могла бы "исправить" это впоследствии.Что вам нужно сделать, это принудительно разделить float и округлить результат:
int result = (int)Math.ceil( ((float)3) / ((float)2) );
Разве это не обычный случай целочисленного деления?Попробуйте математику.Завершите после приведения любого числа к типу с плавающей запятой.
Многие языки "думают" подобным образом.Если вы делите int на int, то вы должны получить int (таким образом, они усекаются, и в результате вы получаете 1).
Мы все знаем, что это неправда, но именно так они работают.Вы можете "обмануть" их и сделать что-то вроде преобразования одного из них в double или использовать двойное представление: Math.ceil (3.0 / 2)
или Math.ceil((double)3/2)
, как уже упоминалось.
Математический центр будет справка, при условии, что вы используете числа с плавающей запятой.Проблема в том, что 3/2 при целочисленном делении равно 1.К тому времени, когда значение попадает в любую функцию, будь то Math.ceil или что-то еще, значение будет просто 1.Любая конечная десятичная часть исчезла.
if (a % b == 0)
{
return (a / b);
}
else
{
return (a / b) + 1;
}
Использует целочисленное деление, чтобы делать то, что вы хотите.Я не знаю математической функции, которая делает это, но почему бы не использовать свою собственную?
приведенный ниже фрагмент также работает с отрицательными целыми числами:
public static int divRoundUp(int x, int n) {
if (n<=0) throw new RuntimeException("conceived wt. pos. dividers (was:"+n+")");
int ret = (x+(n-1)*(x>0?1:0))/n;
return ret;
}
Больше всего мне нравится ответ Рэнди Проктора.Здесь более подробно:
Если вы хотите сделать реальное округление (т.е.3/2 -> 2, но 17/7 -> 2) с целыми числами > 0:использование (dividend + (divisor / 2)) / divisor
вместо того , чтобы dividend / divisor
.
Если дивиденд может быть любым целым числом (т.е.допускается отрицательный):(dividend >= 0) ? ((dividend + divisor / 2) / divisor) : ((dividend - divisor / 2) / divisor)
.
Если дивиденд является любым целым числом, а делитель - любым целым числом, кроме 0:(dividend >= 0) ? ((dividend + Math.abs(divisor) / 2) / divisor) : ((dividend - Math.abs(divisor) / 2) / divisor)
.
(Обратите внимание, что сложение и вычитание могут привести к завершению, которое в противном случае не произошло бы, что делает результат неверным.)
Вот метод, который я создал для обработки деления int без использования Math Round и приведения к float .Это работает для положительных и отрицательных чисел.Это работает путем добавления половины знаменателя, чтобы компенсировать округление в меньшую сторону
public static int div_Int(int num, int den){
if(num > 0 && den > 0 || num < 0 && den < 0 ){
return ((2*num)+ den)/(2*den);
}else{
return ((2*num)- den)/(2*den);
}
}
Если вы хотите просто разделить на 2, вы можете сделать:
n - n / 2
И в целом:
(n - 1) / d + 1 == (n + d - 1) / d
Это справедливо для неотрицательных целых чисел.Как расширить его до отрицательных целых чисел, зависит от того, что вы подразумеваете под "округляет таким образом".Целочисленное деление округляется в сторону нуля, тогда как Math.ceil()
округляет и Math.floor()
округляет в меньшую сторону.Например n / 2 != (int) Math.floor(n / 2.0)
для n == -5
.
Если вы хотите всегда округлять, вы можете использовать Math.ceil()
как в этот ответ.
Если вы действительно хотите избежать использования ceil и casting , вот небольшой метод, который выполняет то же самое.
public int findCeil(int X, int Y) {
if (X % Y == 0){
return X / Y;
} else {
return X / Y + 1;
}
}
Вы пробовали Math.floor()
?