작성
·
115
0
for (int i = 2; i <= 10000000; i++)
{
if (num[i] != 0)
{
long long temp = num[i];
while ((double)num[i] <= (double)B/(double)temp && (double)num[i] >= (double)A / (double)temp)
{
count++;
temp = temp * num[i];
}
}
}
풀이와 다르게 while 문에서 min값까지 판단하게되면 왜 답이 달라지는건지 모르겠습니다.
어떤 값을 count 못하게 되는건지 모르겠습니다
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
winwincs님, 질문 주셔서 감사합니다.
코드 내용에 대해 설명드리면, 여기서 num
배열은 소수들을 담고 있는 것으로 추정됩니다. 배열 안의 각 소수에 대해 거듭제곱한 값이 A와 B 사이에 있는지 확인하는 로직으로 보입니다.
while
문의 조건은 num[i]
를 temp
로 거듭제곱한 값이 A 이상이고 B 이하일 동안 count
를 증가시키는 것입니다. 문제는 num[i]
가 실수로 변환되었을 때, 부동소수점 연산의 오차 때문에 정확한 비교가 어려울 수 있다는 점입니다.
min 값까지 판단하면서 답이 달라지는 부분은, 이 부동소수점 연산 오차 때문에 정확한 범위 판단이 이루어지지 않거나, 배정밀도(double)의 한계로 인해 매우 큰 정수 값에 대한 비교가 정확하지 않을 수 있습니다. 그 결과 일부 값을 계산에서 누락하거나 잘못 포함할 수 있습니다.
부동소수점 연산 오차를 줄이기 위해서는 정수 연산을 사용하는 것이 좋은데, 이 경우 while
조건을 다음과 같이 변경할 수 있습니다:
while (temp <= B / num[i] && temp >= A / num[i]) {
count++;
temp *= num[i];
}
이렇게 하면 temp
값이 A
보다 크거나 같고 B
보다 작거나 같을 때까지 반복하며 count
를 증가시키게 됩니다. 그럼 필요한 정수의 범위 안에서 정확한 판단이 가능하게 됩니다.
참고로 현재 코드의 temp
값이 매우 커질 경우, 실수로의 변환 과정에서 오차가 발생할 수 있기 때문에 이런 연산 방식을 권장드립니다.
추가적으로, 해당 알고리즘과 코딩테스트에 관한 강의나 자료가 필요하시다면 인프런에서 관련 강의를 찾아보시는 것도 좋을 것입니다.