[java] Math.ceil을 사용하여 Java 반올림 int

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

왜 여전히 4를 반환합니까? 157/32 = 4.90625, 반올림해야합니다. 둘러 보았는데 이것이 올바른 방법 인 것 같습니다.

나는 노력 total으로 double유형, 그러나 4.0을 얻을.

내가 뭘 잘못하고 있죠?



답변

157/32두 개의 정수를 서로 나누는 작업 을 수행 하면 항상 내림 된 정수가됩니다. 따라서는 (int) Math.ceil(...)아무것도하지 않습니다. 원하는 것을 달성하기위한 세 가지 가능한 솔루션이 있습니다. 나는 추천 중 하나를 사용하여 옵션 1 또는 옵션 2 . 옵션 0을 사용 하지 마십시오 .

## 옵션 0

두 배로 변환 a하고 원하는대로 b나누기를 사용할 수 있습니다 Math.ceil. 그러나 이중 나눗셈은 부정확 할 수 있으므로이 방법을 사용하지 않는 것이 좋습니다. double의 부정확성에 대해 자세히 알아 보려면 이 질문을 참조하십시오 .

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

##옵션 1

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

당신이 할 a / b경우 항상 바닥 ab양의 정수입니다. 그런 다음 인라인 if 문 마녀가 바닥 대신 천장을해야하는지 여부를 확인합니다. 따라서 +1 또는 +0, 나눗셈에 나머지가 있으면 +1이 필요합니다. a % b == 0나머지를 확인합니다.

## 옵션 2

이 옵션은 매우 짧지 만 다소 덜 직관적 일 수 있습니다. 나는이 덜 직관적 인 접근 방식은 빠른 이중 분열과 비교 방식보다 것이라고 생각 :
이가 일을하지 않는하시기 바랍니다 참고 b < 0.

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), Wikipedia 의 정의와 플롯을 사용합니다 .여기에 이미지 설명 입력

바닥과 천장 함수의 플롯을 통해 관계를 볼 수 있습니다.

바닥 기능 Ceil 기능

당신은 그것을 볼 수 있습니다 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에서 물어볼 수도 있습니다 .


답변

157/32는 int/int이며 결과는 int.

– 이중 문자 그대로 사용해보십시오 157/32d이다, int/double하는 결과를 double.


답변

157/32접미사로 달리 지정하지 않는 한 모든 숫자 리터럴은 정수이므로 정수 나눗셈 입니다 (long의 d경우 double l)

나누기는 이중 (4.0)으로 변환되기 전에 반 내림 (4로) 된 다음 반올림됩니다 (4.0으로).

변수를 사용하면 피할 수 있습니다.

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


답변

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


답변

가장 직관적 인 것은 아무도 언급하지 않았습니다.

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

이 솔루션은 이중 나누기 부정확성을 수정합니다 .


답변

Java에서 .0을 추가하면 두 배가됩니다.

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


답변

두 정수를 나눌 때, 예 :

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

결과는 int값을로 a나누고 b0으로 반올림 한입니다. 결과가 이미 반올림되었으므로 ceil()아무 작업도하지 않습니다. 이 반올림은 floor()음의 무한대 로 반올림하는과 동일하지 않습니다 . 따라서 3/2같음 1(및 floor(1.5)같음 1.0, 그러나 (-3)/2같음 -1(그러나 floor(-1.5)같음)-2.0 )).

경우가 있기 때문에 의미가 a/b항상 동일하다 floor(a / (double) b)다음 방금 구현할 수 ceil()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)는 항상보다 1보다 크므로 작동합니다 . 따라서 정수 가 아닌 경우 다음 정수와 충돌 (또는 과거)하려고합니다 . 첨가floor(a/b)a/ba/b1 - 1 / b 됩니다. 정수의 경우 다음 정수로 밀어 붙이지 않습니다. 그 밖의 모든 경우에는 그럴 것입니다.

Yikes. 이해가 되길 바랍니다. 나는 그것을 설명하는 더 수학적으로 우아한 방법이 있다고 확신합니다.