Есть ли какая-нибудь функция Java или утилита class
, которая округляет таким образом: func(3/2) = 2
Math.ceil()
не помогает, что, по названию, должно было сделать. Я знаю BigDecimal
, но мне это не нужно.
Есть ли какая-нибудь функция Java или утилита 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
Чтобы преобразовать разделение пола в разделение потолка:
(numerator + denominator-1) / denominator
Чтобы преобразовать деление этажа в деление с округлением:
(numerator + (denominator)/2) / denominator
ceil(n/d) = fl((n - 1)/d) + 1
- person Gil Vegliach; 09.01.2017
Вы всегда можете сыграть первыми:
Math.ceil((double)3/2)
В Java 3/2 = 1, поскольку используется целочисленное деление. Нет функции, которая могла бы "исправить" это впоследствии. Что вам нужно сделать, так это вызвать деление с плавающей запятой и округлить результат:
int result = (int)Math.ceil( ((float)3) / ((float)2) );
Разве это не обычный случай целочисленного деления? Попробуйте Math.Ceil после преобразования любого числа в тип с плавающей запятой.
Многие языки так «думают». Если вы делите int на int, вы должны получить int (поэтому они усекаются, и в результате вы получаете 1).
Все мы знаем, что это неправда, но они работают именно так. Вы можете «обмануть» их и сделать что-то вроде преобразования одного из них в двойное, или использовать двойное представление: Math.ceil (3.0 / 2)
или Math.ceil((double)3/2)
, как упоминалось.
Math.ceil поможет, если вы используете числа с плавающей запятой. Проблема в том, что 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;
}
Если вы хотите просто разделить на 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 и литья, вот небольшой метод, который выполняет то же самое.
public int findCeil(int X, int Y) {
if (X % Y == 0){
return X / Y;
} else {
return X / Y + 1;
}
}
Мне больше всего нравится ответ Рэнди Проктора. Здесь поподробнее:
Если вы хотите выполнить реальное округление (т.е. 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);
}
}
Вы пробовали Math.floor()
?