Есть ли какая-либо функция Java или класс util, который выполняет округление таким образом:функция (3/2) = 2?

StackOverflow https://stackoverflow.com/questions/1074228

  •  21-08-2019
  •  | 
  •  

Вопрос

Есть ли какая-нибудь 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() ?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top