RATIO 질문입니다

  • User Avatar
    Mac
    #include <stdio.h>
    #include <math.h>
    int main(){
        int T,N,M,Z;
        scanf("%d",&T);
        while (T--){
            scanf("%d%d",&N,&M);
            Z = (double)M/N*100+1;
            if (Z<100)
                printf("%d\n",(int)ceil((double)(100*M-Z*N)/(Z-100)));
            else
                printf("-1\n");
        }
        return 0;
    }~~~
    
    
    요게 코드고 제가 코드를 짜다가 어느분걸 봤는데 제거랑 비슷한데 훨씬 간결해보여서 가져와서 답을 올려봤는데 자꾸 오답이 나더라구요.
    
    문제 댓글에있는 입력도 다입력해보고 999999999 899999999 이렇게도 넣어보고 해도 맞는답이 나오는데 왜 자꾸 오답이 나는지 알수가 없어서 오답이 알고싶어서 질문드립니다.
    

    12년 전
6개의 댓글이 있습니다.
  • User Avatar
    kcm1700

    식을 검토는 안 해봤지만 식이 맞다면 실수 오차 때문에 문제가 생길 여지가 있는 코드로 보입니다. Z 값이 N으로 나눠졌다 N이 다시 곱해지는데 그러면 안됩니다. 이 문제는 실수 하나도 안 쓰고 해결할 수 있으니 식을 잘 정리해보시면 어떨까요


    12년 전 link
  • User Avatar
    Mac

    그런데 어차피 Z가 정수형으로 바뀌는데도 실수오차가 생기나요 ?? 이부분이 좀 모잘라서 잘모르겠네요 ..


    12년 전 link
  • User Avatar
    wookayin

    http://ideone.com/4GN10F 를 참고하세요.


    12년 전 link
  • User Avatar
    kcm1700

    what every computer scientist should know about floating-point arithmetic 이 문서 검색해서 찬찬히 읽어보세요. 보통의 프로그래밍 언어에서는 실수를 정확히 보관하지 못합니다


    12년 전 link
  • User Avatar
    Mac


    ~~~c++
    #include
    #include
    int main(){
    int T,N,M,Z;
    scanf("%d",&T);
    while (T--){
    scanf("%d %d",&N,&M);
    Z = (double)M/N*100+1;
    if (Z<100){
    if ((Z*N-100*M)%(100-Z)!=0)
    printf("%d\n",((Z*N-100*M)/(100-Z))+1);
    else
    printf("%d\n",((Z*N-100*M)/(100-Z)));
    }
    else
    printf("-1\n");
    }
    return 0;
    }

    이렇게도 바꿔봤는데 .. 애초에 실수를 안쓰는게 답인가요 ? ㅜ
    어느부분을 수정해야하는거죠 ..


    12년 전 link
  • User Avatar
    kcm1700

    식이 정확한지 여부는 확인 안 해봤어요.
    여전히 실수 연산에 문제의 여지가 있네요. N에 5의 배수가 들어갈 경우 실수 오차로 인한 문제가 생길 수 있어요. 실수를 굳이 사용하고자 하신다면 실수가 어떻게 표현되는지 이해하고 의도하지 않은 결과가 생기지 않도록 처리하는 방법을 공부하셔야 합니다.
    epsilon을 사용한 방법 등이 있고, 특히 이 경우에는 전부 정수 연산으로 바꿀 수 있습니다.


    12년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.