자바 과제 질문 제가 학교에서 자바 과제를 받았는데 수업을 들었는데도 뭔소린지 잘모르겠어요 이사진을보고
제가 학교에서 자바 과제를 받았는데 수업을 들었는데도 뭔소린지 잘모르겠어요 이사진을보고 종이에다가 뭘 하나하나 쓰라는데 뭘 써야되나요? 00001000 이런거 배웠던것 같은데
이런 ㅠㅠ 과제 풀이에 어려움이 있나보군요... 걱정마세요~ 학생들 스트레스 받게하는 못된 과제 녀석 제가 물리쳐 드리겠습니다. ^^
참고로 설명이 상당히 길기 때문에 전부다 따라적으실 필요는 없고 핵심 포인트들 위주로 따라적으시면 될 것 같습니다.
비트 연산을 실제로 하는 부분 위주로 따라적으시면 될 것 같구요. 잘 이해가 안되시면 추가 질문주세요.
이렇게 정성스러운 과제 풀이 답변에 채택 안해주시면 저 그냥 울겠습니다 ㅠㅠ
제 노력이 헛되지 않았기를...
&는 비트 AND(논리곱) 연산자입니다.
|는 비트 OR(논리합) 연산자입니다.
^는 비트 XOR(Exclusive Or, 베타적 논리합) 연산자입니다.
~는 비트 NOT(논리 부정) 연산자입니다.
9 & -4
9 | -4
9 ^ -4
~9
~(-4)
이렇게 9와 -4를 각각 비트 연산자를 이용해서 비트 연산을 했을 때 풀이 과정이랑 나오는 결과를 서술하라는 얘기입니다. &, |, ^ 이렇게 3개는 피연산자가 2개 필요하지만 ~는 피연산자가 1개 필요합니다.
피연산자라는건 연산자의 연산 대상입니다.
현대의 모든 컴퓨터는 음수를 2의 보수법으로 표현합니다. 당연히 C, Java에도 적용되는 개념입니다.
보수는 1의 보수와 2의 보수로 나뉩니다. 1의 보수는 비트를 반대로 뒤집는 것이고 2의 보수는 1의 보수의 결과에 1을 더해준 겁니다. 음수를 표현하는 방법은 1의 보수와 2의 보수가 있지만 현대의 모든 컴퓨터는 2의 보수를 사용하고 1의 보수는 사용하지 않습니다. -4는 양수 4의 비트를 먼저 반전시킨 다음에 1을 더해서 구해야 됩니다. 여기서는 진수 변환에 대해서는 따로 설명드리지 않습니다. 진수 변환 관련해서는 유튜브 영상 참고하시기 바랍니다. 글로 설명하기에는 잘 이해도 안 될뿐더러 얘기가 길어집니다. 진수 변환은 눈으로 보고 직접 많이 풀어봐야 금방 이해가 됩니다. 결국, 질문자님의 의도는 과제 해결하는게 주목적이니까 저는 진수 변환은 따로 설명드리지 않겠습니다. 궁금하시면 유튜브 영상 참고 부탁드리겠습니다.
0000 0000 0000 0000 0000 0000 0000 0100(10진수 4를 2진수로 표현)
1111 1111 1111 1111 1111 1111 1111 1011(-4를 1의 보수로 표현)
1111 1111 1111 1111 1111 1111 1111 1100(-4를 2의 보수로 표현)
자바는 C언어와 다르게 부호 없는 키워드(unsigned)가 따로 없습니다.
C언어는 unsigned 키워드로 음수 표현을 제한시키고 부호 비트까지 양수 표현에 사용해서 음수를 표현하지 못하는 대신에 양수의 표현 범위를 확장시키는 프로그래밍이 가능합니다.
부호 있는 정수 자료형에서는 맨 첫 번째 비트가 부호 비트가 됩니다. 부호 비트가 1이면 음수고 0이면 양수입니다. 맨 첫 번째 비트를 MSB(최상위 비트)라고 합니다. 맨 마지막 비트는 LSB(최하위 비트)라고 부릅니다. 보수를 사용하는 이유는 컴퓨터에는 덧셈 회로만 있습니다. 컴퓨터는 덧셈 기능만 있습니다. 컴퓨터는 덧셈 연산만 할줄 아는 녀석입니다. 회로의 크기를 줄이기 위해서이기도 하지만, 컴퓨터는 덧셈 연산이 가장 효율적이기도 하기 때문입니다.
그러면 만약에 우리가 4 빼기 4를 입력하면 컴퓨터는 어떻게 처리할까요? 이때 사용하는 개념이 보수입니다. 보수는 영어로 Complement입니다. 보충해주다, 그런뜻입니다. 컴퓨터는 뺄셈을 시켜도 덧셈을 하는 녀석입니다. 단, 보수를 사용해서 덧셈을 합니다.
보수는 말 그대로 보충해주는 수입니다, 보수를 이용해서 덧셈을 하면 뺄셈을 한 것과 같은 결과를 얻을 수가 있습니다. 보수는 덧셈을 했을 때 뺄셈의 결과를 얻기 위해서 사용하는 개념입니다. 현대의 모든 컴퓨터는 2의 보수법을 사용합니다. 1의 보수는 사용하지 않습니다. 1의 보수를 사용하지 않는데는 결정적으로 2가지 이유가 있습니다. 첫 번째 이유는 1의 보수를 사용하면 -0과 +0 이렇게 0이 2개가 존재합니다. 비트 1개가 낭비되죠. 두 번째 이유는 2의 보수를 사용해서 연산을 하면 바로 10진수로 연산한 것과 같은, 동일한 결과를 얻어낼 수가 있는데 1의 보수는 그렇지 않습니다. 그래서 현대의 모든 컴퓨터는 2의 보수법을 채택합니다.
궁금하실 수도 있으니까 보수를 이용해서 덧셈 해보겠습니다. 실제로 뺄셈 결과가 나오는지 볼까요?
32비트는 너무 기니까 일단, 간단하게 8비트로 표현해보죠.
0000 0100(4)
1111 1011(4를 1의 보수로)
둘이 더하면 1111 1111 이렇게 되죠?
2의 보수니까 여기서 1을 더해주면 자릿수가 하나 올라가죠?
1 0000 0000 원래는 이렇게 나와야지만 우리는 최대 8비트만 가지고 있잖아요?
그래서 1자리 올라간 비트는 버려집니다. 결국, 0000 0000만 남고 이건 10진수로 해도 0이죠.
이렇게 올라간 비트는 캐리 비트(Carry Bit)라고 부릅니다. 넘어간 캐리는 버려지고 0만 남죠.
4랑 보수를 사용한 4를 서로 더했더니, 4+4의 결과가 아니라 4-4의 결과인 0이 나왔죠?
덧셈을 했는데 뺄셈 결과가 나오다니... 이게 보수입니다. 특이하죠.
일단, TMI는 여기까지 하고... 본론으로 넘어갑시다.
비트 연산을 하려면 우선, 10진수를 2진수로 변환해야 합니다.
0000 0000 0000 0000 0000 0000 0000 1001(10진수 9를 32비트 2진수로 표현한 것)
1111 1111 1111 1111 1111 1111 1111 1100(2의 보수법으로 표현한 -4, 위에서 2의 보수 결과랑 똑같죠)
지금 9 & -4 하고있는 겁니다. 비트 AND 연산이니까 두 비트가 모두 1이어야 1이고 나머지 경우는 모두 0입니다.
0000 0000 0000 0000 0000 0000 0000 1000 이렇게 나옵니다. 이걸 다시 10진수로 변환하면 8입니다.
진수 변환하는 방법은 앞에서도 말씀드렸지만 워낙 얘기가 길어질 것 같아서 설명은 생략합니다.
아무튼 9 & -4의 결과는 8입니다.
이번엔 9 | -4 시작하겠습니다.
0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 1100
비트 OR 연산은 두 비트 중에서 하나라도 1이면 1이 됩니다.
이렇게 됩니다.
1111 1111 1111 1111 1111 1111 1111 1101
이걸 10진수로 변환하면 -3입니다.
다시 한 번 강조드리지만 부호 비트가 1이니까 이건 음수라는 것을 알 수 있습니다.
9 | -4의 결과는 -3입니다.
9 ^ -4 시작하겠습니다.
이녀석은 약간 특이합니다. 이녀석은 두 비트가 서로 달라야 1이 되고 서로 같으면 0이 됩니다.
그래서 베타적 논리합이라고 부릅니다.
0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 1100
비트 XOR 연산을 하게되면 이렇게 됩니다.
1111 1111 1111 1111 1111 1111 1111 0101
이걸 10진수로 변환하면 -11입니다.
이게 왜 -11인지 궁금하면 11을 1의 보수로 만들고 그 결과에다가 1을 더해서 2의 보수로 표현해서 비트를 비교해보면 되겠죠. 아까전에 자바는 음수를 2의 보수법으로 표현한다고 했으니까요.
~9 이거 해보겠습니다. ~는 비트 NOT 연산자인데 말 그대로 비트를 반대로 뒤집는 겁니다. 비트를 반전시키는 연산자입니다. 1은 0으로, 0은 1로 뒤집습니다.
0000 0000 0000 0000 0000 0000 0000 1001
이걸 반대로 뒤집으니까 이렇게 되겠죠.
1111 1111 1111 11111 1111 1111 1111 0110
이걸 10진수로 변환하면 -10입니다.
~9의 결과는 -10입니다. 여기서 뭔가 느껴지지 않아요?
제 설명을 열심히 들었다면 무언가 머리에 번쩍거렸을 겁니다.
~ 연산자는 마치 1의 보수와 똑같아보이지 않나요?
1의 보수가 비트를 반대로 뒤집는 거라고 했잖아요.
~ 연산자가 1의 보수 역할을 해주니까 9를 1의 보수로 해서 -10이 되고 여기다가 1을 더해서 2의 보수로 만들어주면 -9가 된다는 사실! -10에다가 1을 더하면 -9잖아요.
우리는 여기서 1가지 결론을 내릴 수 있습니다.
양수에다가 ~ 연산자를 사용하면 절대값의 크기가 1 증가하고 음수 부호가 붙는다는 것을요.
반대로 음수에다가 ~ 연산자를 사용하면 절대값의 크기가 1 감소하고 음수 부호가 사라진다는 것을요.
뭐, 아무튼 ~9는 -10입니다.
~(-4) 마지막으로 이겁니다.
1111 1111 1111 1111 1111 1111 1111 1100
이걸 반대로 뒤집으면 되는거잖아요?
0000 0000 0000 0000 0000 0000 0000 0011 이렇게 되죠.
이걸 10진수로 변환하면 3입니다.
~(-4)의 결과는 3이라는 것을 알 수 있죠. 이렇게 문제 풀이는 마치겠습니다.
앞에서 설명한 것처럼 절대값의 크기가 1 줄어들고 음수 부호가 사라졌죠.
기나긴 설명 들어주셔서 감사합니다.
실제로 소스 코드로 작성해서 실행해보면 다음과 같이 제가 설명한 결과값이 그대로 나오게 됩니다.
이렇게 하나하나 결과가 왜 이렇게 나오는지 원리를 증명, 설명하라는 의의에서 과제 제출을 하신 것입니다.
단순히 결과값만 적으라고 한다면 대부분의 학생들은 그냥 자바 실행 결과 그대로 따라적기만 할테니까요.
참고로 이 개념은 자바 뿐만 아니라 C언어에도 똑같이 적용됩니다.
사진은 자바 컴파일러가 아니라 C 컴파일러로 찍은 사진이긴 한데 자바 컴파일러에서도 동일한 실행 결과 나옵니다. 자바 컴파일러에서도 동일한 결과 나오는거 확인했으니까 걱정 안하셔도 되구요.
애초에 이러한 컴퓨터 개념들은 자바한테만 적용되는게 아니기 때문에.. C 컴파일러로 하든, 자바 컴파일러로 하든 실행 결과가 다를리가 없지요. 제가 이렇게 자세하게 설명을 드린 이유는 단순히 과제 제출 목적으로만 생각하지 마시고 자바라는 프로그래밍 언어를 보다 깊이있게 이해하시는데 도움이 되시길 바래서입니다.
진수 변환은 정말 간단한 개념이니까 혹여나 모르신다면 유튜브 영상 시청해서라도 꼭 숙달하시기 바랍니다. 진수 변환은 생각보다 자주 쓰입니다. 꼭 알고계셔야 합니다.
이해가 안되는 부분에 대해서는 추가 질문을 주시면 성심성의껏 답변드리겠습니다.
자바 과목 A+ 받으시기 바랍니다. ^^ 자바는 클래스, 상속부터 진짜 재밌어지는데 ㅎㅎ
수업 열심히 들어보세요~ 자바 재밌습니다. 저는 자바보다 C언어를 더 좋아하지만요.