[ 자바의 정석 Chapter3.연산자 - 연습문제 ]
3-1. 다음 연산의 결과를 적으시오
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Exercise3_1
{
public static void main(String[] args)
{
int x = 2;
int y = 5;
char c = 'A'; // 'A'의 문자코드는 65
System.out.println(1 + x << 33);
System.out.println(y >= 5 || x < 0 && x > 2);
System.out.println(y += 10 - x++);
System.out.println(x+=2);
System.out.println( !('A' <= c && c <='Z') );
System.out.println('C'-c);
System.out.println('5'-'0');
System.out.println(c+1);
System.out.println(++c);
System.out.println(c++);
System.out.println(c);
}
}
|
cs |
☞ 6 / true / 13 / 5 / false / 2 / 5 / 66 / B / B / C
① 1+x << 33 : x의 값이 2이므로 1+2<<33이 되고 덧셈연산자 + 보다 쉬프트 연산자 <<의 우선순위가 낮기 때문에 1+2가 먼저 연산되어 3<<33이 된다. int 는 32bit이므로 33번 쉬프트 하지 않고 1번만 쉬프트하게 된다. 그렇기 때문에 3<<33 은 3<<1과 같고 <<1은 2의 1제곱인 2를 곱하는 것과 같으므로 3<<1은 3*2가 되어 6의 값을 갖게된다.
② y>=5 || x<0 && x>2 : 논리연산자 ||과 && 중에서 && 의 우선순위가 더 높기 때문에 x<0 && x>2 를 먼저 보면 x는 2의 값을 갖기 때문에 0보다 작지 않기 때문에 false가 되고, y>=5를 보면 y는 5의 값을 갖기 때문에 true가 된다. 그래서 true || false가 되는데 논리 OR 연산자 ||는 한 개의 조건만 true여도 전체식을 true로 보기 때문에 true가 출력된다.
③ y += 10 - x++ : y=y+(10-x++)에서 x++은 기존의 값 2가 대입된 후 x++이 진행되어 대입되기 때문에 y=y+8 가 된다. y는 5의 값을 가지므로 y=13이 된다.
④ x+=2 : x=x+2에서 x는 2의 값이지만 위의 식에서 x++된 값이 여기에 대입되기 때문에 x=3+2가 되어 x=5의 값을 갖게 된다.
⑤ !('A' <= c && c <='Z') : 위에서 char c는 'A'의 값을 갖기 때문에 다시 보면 !('A'<='A' && 'A'<='Z') 가된다. 'A'는 'A'보다 크거나 같으며 'Z'보다 작거나 같기 때문에 괄호 안의 식은 true의 값을 갖는다. !(true)이기 때문에 결과는 false가 된다.
⑥ 'C'-c : 위에서 char c는 'A'의 값을 갖고 'A'는 65, 'B'는 66, 'C'는 67이기 때문에 'C'-'A' 는 67-65가 되어 2의 값을 갖는다.
⑦ '5'-'0' : char + char 혹은 char - char은 둘 다 int형으로 바뀌어 계산된다. '0'은 48, '1'은 49, '2'는 50, '3'은 51, '4'는 52, '5'는 53의 값을 갖기 때문에 '5'-'0'은 53-48이 되어 5가 출력된다.
⑧ c+1 : char c 는 'A'의 값을 가졌고 'A'는 65이기 때문에 65+1이 되어 66이 출력된다.
⑨ ++c : 단항연산자인 ++은 위에서 이항연산자가 피연산자 int보다 작은 타입(byte, short, char)이라고 해도 int로 형변환을 하지 않는다. 그래서 c는 'A'의 값 65에서 ++로 인해 1 증가하여 66이 되고 int로 형변환하여 66이 출력되는 것이 아니라 형변환하지 않기 때문에 66의 값을 가지는 B로 출력된다.
⑩ c++ : 단항연산자인 ++은 위에서 이항연산자가 피연산자 int보다 작은 타입(byte, short, char)이라고 해도 int로 형변환을 하지 않는다. 위에서 c는 'B'의 값 66이 되었고 c++은 현재 가진 값 그대로 대입된 후 이후에 1증가 되기 때문에 B가 출력된다.
⑪ c : 단항연산자인 ++은 위에서 이항연산자가 피연산자 int보다 작은 타입(byte, short, char)이라고 해도 int로 형변환을 하지 않는다. 위에서 c는 'B'의 값 66이 되었고 c++로 인한 1 증가가 여기에서 이루어져 67이 되고 67은 C의 값이므로 C가 출력된다.
3-2. 아래의 코드는 사과를 담는데 필요한 바구니(버켓)의 수를 구하는 코드이다. 만일 사과의 수가 123개이고 하나의 바구니에는 10개의 사과를 담을 수 있다면 13개의 바구니가 필요할 것이다. (1) 에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
9
10
|
class Exercise3_2
{
public static void main(String[] args)
{
int numOfApples = 123; // 사과의 개수
int sizeOfBucket = 10; // ( ) 바구니의 크기 바구니에 담을 수 있는 사과의 개수
int numOfBucket = ( /* (1) */ ); // 모든 사과를 담는데 필요한 바구니의 수
System.out.println("필요한 바구니의 수 : " + numOfBucket);
}
}
|
cs |
☞ numOfApples/sizeOfBucket + (numOfApples%sizeOfBucket > 0 ? 1 : 0)
정수간의 나눗셈 연산에서는 나머지를 버리는 특성이 있다.
numOfBucket은 10개씩 담을 바구니의 개수+10개가 안되는 잔여 사과에 대한 바구니에 대한 판단을 해주면 된다.
numOfApples/sizeOfBucket 에서 123/10 하면 3이 남게 되는데 정수간의 나눗셈 연산에서는 나머지를 버리는 특성이 있기 때문에 10개에 속하지 못한 나머지의 사과의 값은 버리게 된다.
numOfApples%sizeOfBucket > 0 ? 1 : 0 에서 numOfApples%sizeOfBucket을 한 값은 0이거나 0보다 큰 경우만 생기는데 0보다 큰 경우 1개의 바구니가 더 필요하기 때문에 1을, 0보다 크지 않은 경우는 바구니가 더 필요하지 않기 때문에 0을 연산하게 된다.
3-3. 아래는 변수 num의 값에 따라 ‘양수’, ‘음수’, ‘0’ 을 출력하는 코드이다. 삼항 연산자를 이용해서 (1)에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
|
class Exercise3_3
{
public static void main(String[] args)
{
int num = 10;
System.out.println(/* (1) */ );
}
}
|
cs |
☞ num >= 1 ? "양수" : (num < 0 ? "음수" : 0)
num의 값이 양수면 양수로 출력, 양수가 아닐 경우 음수인지, 0인지 판단하여 출력한다. num의 값이 1보다 크거나 같으면 양수이고, 아닐 경우 num이 0보다 작다면 음수, 아니라면 0을 출력한다.
3-4. 아래는 변수 num의 값 중에서 백의 자리 이하를 버리는 코드이다. 만일 변수 num의 값이 ‘456’이라면 ‘400’이 되고, ‘111’이라면 ‘100’이 된다. (1)에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
|
class Exetcise3_4
{
public static void main(String[] args)
{
int num = 456;
System.out.println(/* (1) */);
}
}
|
cs |
실행결과 : 400
☞ num/100*100
정수간의 나눗셈 연산을 통해 나머지를 버리도록 해준다. num의 값이 456일 경우 100으로 나누면 56이 남게되는데 이 값을 버리고 다시 100을 곱해주면 400이 된다. 마찬가지로 num의 값이 111일 경우 100으로 나누면 11이 남게되는데 이 값은 버려지기 때문에 다시 100을 곱해주면 100이 된다.
3-5. 아래는 변수 num의 값 중에서 일의 자리를 1로 바꾸는 코드이다. 만일 변수 num의 값이 333이라면 331이 되고, 777이라면 771이 된다. (1)에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
|
class Exercise3_5
{
public static void main(String[] args)
{
int num = 333;
System.out.println(/* (1) */ );
}
}
|
cs |
실행결과 : 331
☞ num/10*10+1
num의 값 331을 10으로 나누게 되면 나머지 1을 버리고 33이 남게된다. 이 값에 다시 10을 곱해주면 330이 되고 +1을 해주면 331이 된다.
3-6. 아래는 변수 num의 값보다 크면서도 가장 가까운 10의 배수에서 변수 num의 값을 뺀 나머지를 구하는 코드이다. 예를 들어, 24의 크면서도 가장 가까운 10의 배수는 30이다. 19의 경우 20이고, 81의 경우 90이 된다. 30에서 24를 뺀 나머지는 6이기 때문에 변수 num의 값이 24라면 6을 결과로 얻어야 한다. (1)에 알맞은 코드를 넣으시오. [Hint] 나머지 연산자를 사용하라.
1
2
3
4
5
6
7
8
|
class Exercise3_6
{
public static void main(String[] args)
{
int num = 24;
System.out.println( /* (1) */ );
}
}
|
cs |
실행결과 : 6
☞ (num/10+1)*10-num
24에서 크면서도 제일 가까운 10의 배수는 30, 38에서 크면서도 제일 가까운 10의 배수는 40.. 크면서도 제일 가까운 10의 배수는 뒤에 위치한 1의 자리수를 버리고 앞의 자리수에 1이 더해져야 한다. 그리고 1을 더한 수에 다시 10을 곱해 10의 자리로 만들어준 후 여기서 원래의 값을 빼주면 된다.
3-7. 아래는 화씨(Fahrenheit)를 섭씨(Celcius)로 변환하는 코드이다. 변환공식이 ' C = 5/9 x (F - 32) ' 라고 할 때, (1) 에 알맞은 코드를 넣으시오. 단, 변환 결과값은 소수점 셋째자리에서 반올림해야 한다. (Math.round()를 사용하지 않고 처리할 것)
1
2
3
4
5
6
7
8
9
10
11
|
class Exetcise3_7
{
public static void main(String[] args)
{
int fahrenheit = 100;
float celcius = ( /* (1) */ );
System.out.println("Fahrenheit : " + fahrenheit);
System.out.println("Celcius : " + celcius);
}
<span style="font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은
|
실행결과 : Fahrenheit : 100 / Celcius : 37.38
☞ float celcius = ((int)((5/9f * (fahrenheit-32))*100+0.5)/100f);
화씨를 섭씨로 바꾸는 공식이 5/9 x (F - 32) 인데 여기서 5/9는 정수와 정수의 나눗셈 연산이므로
연산하면 0.xxx 인데 나머지를 버려서 5/9는 0의 값을 가지게 된다.
그렇기 때문에 두 피연산자 중 어느 한 쪽을 반드시 float이나 double로 해야만 실수형태의 값을 출력할 수 있다. 그래서 정수형 리터럴인 9대신에 float타입의 리터럴인 9f를 사용한 것이고 소수점 셋째자리에서 반올림을 하려면 다음의 과정을 거쳐야 한다.
① 값에 100을 곱한다.
37.77778 * 100
② 1의 결과에 0.5를 더한다.
3777.778 + 0.5 > 3778.278
③ 2의 결과를 int 타입으로 변환한다.
(int)3778.278 > 3778
④ 3의 결과를 100f로 나눈다. (100으로 나누면 소수점 아래의 값을 잃는다.)
3778/100f > 37.78
3-8. 아래 코드의 문제점을 수정해서 실행결과와 같은 결과를 얻도록 하시오.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
class Exercise3_8
{
public static void main(String[] args)
{
byte a= 10;
byte b = 20;
byte c= a + b;
char ch = 'A';
ch = ch + 2;
float f = 3/2;
long l = 3000 * 3000 * 3000;
float f2 = 0.1f;
double d = 0.1;
boolean result = d==f2;
System.out.println("c=" + c);
System.out.println("ch=" + ch);
System.out.println("f=" + f);
System.out.println("l=" + l);
System.out.println("result=" + result);
}
}
|
cs |
실행결과
c = 30
ch = c
f = 1.5
l = 27000000000
result = true
☞
① byte c = a+b → byte c = (byte)(a+b)
byte+byte 이항연산은 int+int로 자동 형변환 되기 때문에 다시 byte로 형변환 해주어야 한다.
② ch = ch+2 → (char)(ch+2)
'A'는 65의 값을 갖고, char+int가 되어 65+2로 67이 되기 때문에 67을 c로 출력하기 위해서는 다시 char로 형변환 해주어야 한다.
③ float f = 3/2 → float f = 3/2f
실수의 기본 자료형은 double이기 때문에 3/2는 사실 3/2d와 같기 때문에 3/2f로 형변환 시켜주어야 한다.
④ long l =3000 * 3000 * 3000 → long l = 3000 * 3000 * 3000L
int * int * int 의 결과는 자료형으로 int를 갖기 때문에 long 타입의 결과값을 위해서 접미사 L을 붙여 long타입의 리터럴로 만들어주어야 한다.
⑤ boolean result = d==f2 → boolean result = (float)(d==f2)
d 의 자료형은 double이고 f2의 자료형은 float인데 이 경우 double과 double의 연산으로 자동형변환이 일어나게 된다. 실수는 정수와 다르게 근사값으로 표현을 하기 때문에 float을 double로 형변환 하게 될 경우 오차가 발생 할 수 있다. 그렇기 때문에 float을 double로 형변환 하는 것 보다는 double을 float으로 형변환 하여 비교하는 것이 좋다.
3-9. 다음은 문자형 변수 ch가 영문자(대문자 또는 소문자)이거나 숫자일 때만 변수 b의 값이 true가 되도록 하는 코드이다. (1)에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
9
10
11
|
class Exercise3_9
{
public static void main(String[] args)
{
char ch = 'z';
boolean b = ( /* (1) */ );
System.out.println(b);
}
}
|
cs |
실행결과 : true
☞ 'a'<= ch && ch <='z' || 'A' <= ch && ch <= 'Z' || '0' <= ch && ch <= '9'
3-10. 다음은 대문자를 소문자로 변경하는 코드인데, 문자 ch에 저장된 문자가 대문자인 경우에만 소문자로 변경한다. 문자코드는 소문자가 대문자보다 32만큼 더 크다. 예를 들어 'A'의 코드는 65이고 ' a'의 코드는 97이다. (1)~(2) 에 알맞은 코드를 넣으시오.
1
2
3
4
5
6
7
8
9
10
11
12
|
class Exercise3_10
{
public static void main(String[] args)
{
char ch = 'A';
char lowerCase = ( /* (1) */ ) ? ( /* (2) */) : ch;
System.out.println("ch : " + ch);
System.out.println("ch to lowerCase : " + lowerCase);
}
}
|
cs |
실행결과
ch : A
ch to lowerCase : a
☞ 'A'<= ch && ch <= 'Z' ? (char)(ch+32)
'Java > Day8' 카테고리의 다른 글
[Java] 아스키 코드 ASCII & 유니 코드 (0) | 2021.11.12 |
---|---|
[Java] Package 패키지 & import java.lang (0) | 2021.11.12 |
[Java] Java API 도큐먼트 & next와 nextLine (0) | 2021.11.12 |
[Java] 싱글턴 패턴 Singleton Pattern (0) | 2021.11.11 |
[Java] 자바의 정석 Chapter2.변수 - 연습문제 (0) | 2021.11.09 |