boj 2473번 문제를 통해 배우게된 정말정말 중요하고 헷갈리기 쉬운 int overflow에 관하여.
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int n;
ll a[5005];
int ans1,ans2,ans3;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    for(int i=0; i<n; i++) cin>>a[i];
    sort(a,a+n);
    ll ans=3e9+1;
    for(int st=0; st<n-2;st++){
        int mid=st+1;
        int en=n-1;
        while(mid<en){
            ll cur=a[st]+a[mid]+a[en];/*여기서 오른쪽 계산이, int a[5005]; 로
            선언한 상태에서 ll cur= a[st]+a[mid]+a[en]; 으로 작성하면, 
            오른쪽의 연산에서 int overflow가 발생한다. 아주아주 생각을 못해내다가
            뒤늦게 찾았다. 이걸 피하기 위해서는 int a[5005] 로 선언했으면,
            ll cur = (long long)(a[st]+a[mid]+a[en]); 형태로 계산하던지, 
            아니면 1ll을 곱해주어서 캐스팅 해주어야 한다. */
            if(abs(ans)>abs(cur)){
                ans=cur;
                ans1=a[st];
                ans2=a[mid];
                ans3=a[en];
            }
            if(cur>=0) en--;
            else mid++; 
        }
    }
    cout<<ans1<<' '<<ans2<<' '<<ans3;
}
//int overflow 피하는 방법
/*첫번째: long logn a[5005];로 선언하고 ll cur=a[st]+a[mid]+a[en] 로 작성하기*/
/*두번째: int a[5005]; 로 선언하고 ll cur=(long long)(a[st]+a[mid]+a[en])로
작성하기 */
/*세번째: int a[5005]; 로 선언하고 ll cur=1ll*a[st]+a[mid]+a[en]; 로 작성하기*/

/*주의: int a[5005]; 로 선언하고 ll cur=(1ll)*(a[st]+a[mid]+a[en])로 작성하면
int overflow 발생한다. 이건 오히려 굉장히 주의해야할 코드 작성 방법인것 같다. */

/*아무래도 위의 경우들 중에서 가장 좋은 방법은 애초부터 연산의 결과가 int 범위를 넘어서는
 연산을 하는 경우는 그냥 long long a[5005]; 형태로 선언하고 코드를 작성하는게 가장
실수를 줄이면서 int overflow를 방지할 수 있는 방법으로 보여진다. 이런 식으로 
코드를 작성하도록 하자.*/

이번 문제를 해결하면서 int overflow가 발생하는데, 발생하는 위치를 찾는데 어느정도 애를 먹었다. 지속적으로 어디가 int overflow가 발생하는지 파악하지 못했는데, int 로 선언된 a[st]+a[mid]+a[en]의 연산에서 overflow가 발생했다. 

근데 이걸 해결하는 코드 작성 방법에도 해결한것처럼 보이는 경우도 해결한게 아니게 되는 경우도 있어서 이걸 애초부터 여러가지 방법중에서 가장 실수를 할 일이 없도록 애초부터 long long a[5005] 형태로 선언하는것이 가장 좋겠다는 생각을 하게 되었다. 

다음에도 이런식으로 연산을 하게 되는 원소들이 int overflow를 발생할 가능성이 있다면, 애초부터 그 원소들이 각각이 int 범위를 넘지 않더라도 long long 으로 선언해주어서 계산 과정상에서 int overflow가 발생하는걸 방지하도록 해야겠다.

주의하도록 하자. 항상 주의하자. 

 

  Comments,     Trackbacks