ENDIANS 문제 질문 드립니다.

  • sangkoo
    sangkoo

    ENDINANS문제를 풀다가 어려움이 있어 질문 드립니다.

    [[problem:ENDINANS]]
    [[연습 문제|problem:ENDINANS]]

    1. 입력받은 10진수를 2진수로 먼저 변환한 다음에
    2. 그 2진수를 작은 인디언 데이터 저장방식(8개씩 끊어서 순서 바꾸기..)으로 변환한 다음
    3. 다시 그 변환된 2진수를 10진수로 변환시키도록 문제를 해결하려고 하는데요,

    아직 몇 문제를 풀지 입력받는 것은 작성하지 않았습니다.

    중간 중간 제가 변환시킨 것이 맞는지 확인 하도록 출력했는데요
    마지막에 2진수를 10진수로 바꾸는 방법이 틀린 것 같은데
    제 머릿속에서는 이 방법이 맞는 것 같아서요..
    중간 과정은 맞은 것 같은데 마지막 출력 값이 틀리네요..

    문제 이해를 다시 해야할까요
    아니면 2진수에서 10진수로 변환할 때 어떤 문제가 있는걸까요?

    이제 막 시작해서 코드가 지저분하고 난잡해서 죄송합니다.

    #define N 32
    
    int main(void)
    {
        int dec;
        int arr[N], bin[N];
        int tmp[N]; //임시배열
    
        int i, j;
    
        scanf("%d", &dec); //10진수 입력
    
        for (i = 0; i < N; i++) //배열arr[i], bin[i]를 모두 0으로 초기화
        {
            arr[i] = 0;
            bin[i] = 0;
        }
    
        for (i = 0; dec > 0; i++) //10진수가 1이 될때까지 2로 나눈 나머지를 배열arr[i]에 저장
        {
            arr[i] = dec % 2; //배열에 거꾸로 저장이 되어있음
            dec /= 2;
        }
    
        for (j = N - 1, i = 0; j > 0, i < N; j--, i++) //32bit 2진수니까 나머지 0들도 필요하므로, 배열의 크기는 32이지만 인덱스는 0~31까지니까
        {
            bin[i] = arr[j];
        }
    
        printf("10진수에서 2진수로 바꾼 결과값\n");
    
        for (i = 0; i < N; i++)
        {
            printf("%d", bin[i]);
        }
        printf("\n");
    
        //-----------------------------------------------------------------------------------------여기까지 10진수에서 2진수로
    
        int k, p, q;
        for (k = 0, p = 3; k < 32, p >= 0; p--) //8bit로 끊어서 작은인디언 방식으로 변환한 이진수 배열 tmp[]에 임시 저장
        {
            for (q = 0; q < 8; q++)
            {
                tmp[k++] = bin[8 * p + q];
            }
        }
    
        printf("작은인디언 데이터 방식으로 변환한 이진수 값\n");
    
        for (i = 0; i < N; i++)
        {
            printf("%d", tmp[i]);
        }
        printf("\n");
    
        //-------------------------------------------------------------------------------------------여기까지 데이터 변환 과정
    
        int convertDec = 0;
        int num = 1;
        for (i = N - 1; i >= 0; i--)
        {
            if (tmp[i] ==1)
                convertDec += num;
            num *= 2;
        }
    
        printf("%d", &convertDec);
        printf("\n");
    
        return 0;
    
    }
    

    이것을 실행 시키면

    305419896
    10진수에서 2진수로 바꾼 결과값
    000010010001101000101011001111000
    작은인디언 데이터 방식으로 변환한 이진수 값
    01111000010101-----------------(예제값)
    9829156

    이렇게 마지막 값만 예제와 다릅니다.
    출력결과 이미지 추가하는 방법을 몰라서 바로 썼어요..


    6년 전
2개의 댓글이 있습니다.
  • keith
    keith

    질문이 오래되어서, 도움이 될지는 모르겠지만^^ 답변 적어봅니다.

    해당 소스에서 잠정적인 에러 문제로 보이는것은 3가지가 있습니다.
    먼저 dec이라는 변수와 convertDec라는 변수를 int로 사용했다는 점입니다.
    아시다시피 일반적인 컴파일러에서 32비트 정수가 맞긴 하나, "부호가 있는 정수" 입니다. 따라서 마지막 1비트는 부호 비트로 사용되므로, unsigned int 를 사용해 주세요.
    두번째는 마지막 printf의 인자로 주소값을 사용했다는 점입니다.
    printf("%d", &convertDec); 부분을 printf("%u", convertDec); 으로 변경해 주세요^^;;;;; 알고나니 당황스럽죠?^^;
    마지막으로는 scanf와 printf의 형식 지정자도 같이 고려해야 합니다. 위에서 살짝 나왔지만, unsigned int를 위해서는 %d가 아닌 %u로 사용하셔야 합니다.
    추가적으로 사람마다 코딩스타일이 있으니, 뭐가 정답이다.. 이런건 없지만, 만약 공부하신다면 도움이 될 수 있도록 몇가지 팁을 적어드립니다.

    // C나 C++에서 배열을 0으로 초기화할때 굳이, for문을 돌릴 필요가 없습니다.
    int arr[N] = {0}, bin[N] = {0}; // 하시고, 나중에 있는 for문은 삭제하셔도 됩니다.
    // 만약 해당 변수가 재활용 되어, 계속해서 초기화해줘야 할 필요가 있다면. 함수로 별도로 빼신 후, 함수 내에서 해당 변수를 위와같이 선언하거나, 루프문 안에서 변수를 선언하는 방법이 있습니다.
    // 혹시 그마저도 안된다면, memset함수를 활용하시는게 좋습니다. 한줄이면 끝나요.. (속도가 더 빠른지는 확실하진 않음)
    memset(arr, 0, sizeof(int) * N);
    
    for (j = N - 1, i = 0; j > 0, i < N; j--, i++) {
        bin[i] = arr[j];
    } // 굳이 변수를 2개를 쓸 필요가 없어 보입니다. 속도나 가독성의 이점도 그닥 없는것 같습니다. 아래와 같이 바꿔주시는게 어떨까요?(이건 권고사항?^^)
    for (i = 0; i < n; i++) {
        bin[i] = arr[N-1-i];
    }
    

    6년 전 link
  • sangkoo
    sangkoo

    답변이 달리지 않고 문제도 계속 풀리지 않아서 한동안 들어오지 않다가 오늘 문득 궁금해져서 들어왔더니 답글이 달려 있네요. 정말 감사드려요


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