Java округление до int с использованием Math.ceil

int total = (int) Math.ceil(157/32);

Почему он все еще возвращает 4? 157/32 = 4.90625, мне нужно округлить, я огляделся, и это, кажется, правильный метод.

Я пробовал total как double, но получаю 4.0.

Что я делаю неправильно?

Ответ 1

Вы делаете 157/32 который делит два целых числа друг с другом, что всегда приводит к округленному целому числу. Поэтому (int) Math.ceil(...) ничего не делает. Есть три возможных решения для достижения того, что вы хотите. Я рекомендую использовать либо вариант 1, либо вариант 2. Пожалуйста, НЕ используйте опцию 0.

Вариант 0

Преобразуйте a и b в double, и вы можете использовать деление и Math.ceil как вы хотели, чтобы это работало. Однако я настоятельно не рекомендую использовать этот подход, потому что двойное деление может быть неточным. Чтобы узнать больше о неточности двойников, смотрите этот вопрос.

int n = (int) Math.ceil((double) a / b));

Опция 1

int n = a / b + ((a % b == 0) ? 0 : 1); 

Вы делаете a/b с всегда floor, если a и b оба являются целыми числами. Тогда у вас есть встроенный оператор if-Statement, который проверяет, стоит ли вам использовать ceil вместо пола. Так что +1 или +0, если есть остаток с делением, который вам нужен +1. a % b == 0 проверяет остаток.

Вариант 2

Этот вариант очень короткий, но, возможно, для некоторых менее интуитивно понятен. Я думаю, что этот менее интуитивный подход будет быстрее, чем подход двойного деления и сравнения:

int n = (a + b - 1) / b;

Чтобы уменьшить вероятность переполнения, вы можете использовать следующее. Однако, обратите внимание, что это не работает для a = 0 и b < 1.

int n = (a - 1) / b + 1;

Объяснение "менее интуитивного подхода"

Поскольку деление двух целых чисел в Java (и большинстве других языков программирования) всегда будет основывать результат. Так:

int a, b;
int result = a/b (is the same as floor(a/b) )

Но нам нужен не floor(a/b), а ceil(a/b), и мы используем определения и графики из Википедии: enter image description here

С помощью этих графиков функции пола и потолка вы можете увидеть отношения.

Floor functionCeil function

Вы можете увидеть, что floor(x) <= ceil(x). Нам нужен floor(x + s) = ceil(x). Итак, нам нужно найти s. Если мы возьмем 1/2 <= s < 1 это будет просто правильно (попробуйте несколько чисел, и вы увидите, что да, мне самому трудно доказать это). И 1/2 <= (b-1)/b < 1, так

ceil(a/b) = floor(a/b + s)
          = floor(a/b + (b-1)/b)
          = floor( (a+b-1)/b) )

Это не настоящее доказательство, но я надеюсь, что вы довольны этим. Если кто-то может объяснить это лучше, я был бы также признателен. Возможно спросите это на MathOverflow.

Ответ 2

157/32 - int/int, что приводит к int.

Попробуйте использовать двойной литерал - 157/32d, который равен int/double, что приводит к double.

Ответ 3

157/32 - целочисленное деление, потому что все числовые литералы являются целыми числами, если не указано иначе с суффиксом (d для double l для долгого времени)

деление округляется (до 4) до того, как оно преобразуется в двойное (4.0), которое затем округляется (до 4.0)

если вы используете переменные, которые вы можете избежать,

double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);

Ответ 4

int total = (int) Math.ceil((double)157/32);

Ответ 5

В Java добавление 0. сделает его двойным...

int total = (int) Math.ceil(157.0 / 32.0);

Ответ 6

При делении двух целых чисел, например,

int c = (int) a / (int) b;

результат равен int, значение которого равно a, деленное на b, округленное до нуля. Поскольку результат уже округлен, ceil() ничего не делает. Обратите внимание, что это округление не совпадает с floor(), которое округляется к отрицательной бесконечности. Таким образом, 3/2 равно 1floor(1.5) равно 1.0, но (-3)/2 равно -1 (но floor(-1.5) равно -2.0).

Это важно, потому что если a/b всегда совпадают с floor(a / (double) b), тогда вы можете просто реализовать ceil() of a/b как -( (-a) / b).

Предложение получения ceil(a/b) из

int n = (a + b - 1) / b;, что эквивалентно a / b + (b - 1) / b, или (a - 1) / b + 1

работает, потому что ceil(a/b) всегда больше, чем floor(a/b), за исключением случаев, когда a/b является целым числом. Таким образом, вы хотите поднять его до (или минус) следующего целого числа, если a/b не является целым числом. Добавление 1 - 1 / b сделает это. Для целых чисел это не приведет их к следующему целому числу. Для всего остального это будет.

Хлоп. Надеюсь, это имеет смысл. Я уверен, что есть более математически изящный способ объяснить это.

Ответ 7

int total = (int) Math.ceil( (double)157/ (double) 32);

Ответ 8

Также для преобразования числа из целого числа в действительное число можно добавить точку:

int total = (int) Math.ceil(157/32.);

И результат (157/32.) также будет реальным.;)

Ответ 9

Проверьте решение ниже для вашего вопроса:

int total = (int) Math.ceil(157/32);

Здесь вы должны умножить Numerator на 1.0, затем он даст ваш ответ.

int total = (int) Math.ceil(157*1.0/32);

Ответ 10

Использовать двойную печать, например

Math.ceil((double)value) или как

Math.ceil((double)value1/(double)value2);

Ответ 11

Java предоставляет только разделение по умолчанию / по умолчанию. Но мы можем писать потолок с точки зрения пола. Давайте посмотрим:

Любое целое число y можно записать в виде y == q*k+r. Согласно определению разделения пола (здесь floor), который округляет r,

floor(q*k+r, k) == q  , where 0 ≤ r ≤ k-1

и разделения потолка (здесь ceil), который округляет r₁,

ceil(q*k+r₁, k) == q+1  , where 1 ≤ r₁ ≤ k

где мы можем заменить r+1 на r₁:

ceil(q*k+r+1, k) == q+1  , where 0 ≤ r ≤ k-1


Затем подставим первое уравнение в третье для q, получив

ceil(q*k+r+1, k) == floor(q*k+r, k) + 1  , where 0 ≤ r ≤ k-1

Наконец, для любого целого y, где y = q*k+r+1 для некоторого q, k, r, мы имеем

ceil(y, k) == floor(y-1, k) + 1

И мы закончили. Надеюсь, это поможет.

Ответ 12

Никто не упомянул самое интуитивное:

int x = (int) Math.round(Math.ceil((double) 157 / 32));

Это решение исправляет неточность двойного деления.

Ответ 13

Есть два метода, с помощью которых вы можете округлить свое двойное значение.

  1. Math.ceil
  2. Math.floor

Если вы хотите, чтобы ваш ответ 4.90625 был равен 4, вам следует использовать Math.floor, а если вы хотите получить ответ 4.90625 как 5, вы можете использовать Math.ceil.

Вы можете сослаться на следующий код для этого.

public class TestClass {

    public static void main(String[] args) {
        int floorValue = (int) Math.floor((double)157 / 32);
        int ceilValue = (int) Math.ceil((double)157 / 32);
        System.out.println("Floor: "+floorValue);
        System.out.println("Ceil: "+ceilValue);

    }

}

Ответ 14

int total = (157-1)/32 + 1

или более общий

(a-1)/b +1