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
경우 항상 바닥 a
과 b
양의 정수입니다. 그런 다음 인라인 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 의 정의와 플롯을 사용합니다 .
바닥과 천장 함수의 플롯을 통해 관계를 볼 수 있습니다.
당신은 그것을 볼 수 있습니다 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
나누고 b
0으로 반올림 한입니다. 결과가 이미 반올림되었으므로 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/b
a/b
1 - 1 / b
됩니다. 정수의 경우 다음 정수로 밀어 붙이지 않습니다. 그 밖의 모든 경우에는 그럴 것입니다.
Yikes. 이해가 되길 바랍니다. 나는 그것을 설명하는 더 수학적으로 우아한 방법이 있다고 확신합니다.