public class radi {
	public static void main(String[] args) {
		int rad = 3;
		System.out.println(Math.PI);
		System.out.printf("원 둘레는 : %fcm%n" , Math.PI *2*rad);
		System.out.printf("원 넓이는 : %fcm^2%n" , Math.PI *rad*rad);
	}
}
원 둘레는 : 18.849556cm
원 넓이는 : 28.274334cm^2

3-1 다음 연산의 결과를 적으시오

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);
	}
}
6
true
13
5
false
2
5
66
B
B
C

<<는 쉬프트 연산자이고 int는 8*4=32이므로 왼쪽으로 한번 쉬프트 된다.

0011 > 0110 따라서 6을 값으로 가진다.

 

&&연산자 x > 2는 x <0 거짓이므로 y >=5 || (거짓)이 되고 y는 5보다 크므로 참을 반환한다.

 

y += 10 - x++ 은 y = y+10-x++이고 x의 println이 끝나고 연산되므로 y = 5 + 10 - 2 즉 13이 된다.

 

x = x+2인데 위에서 x의 값이 3이 되었으므로 x = 3+2 즉 5가 된다.

 

!(65 <= 65 <= 90) 괄호 안은 참이나,! 가 붙어서 출력되므로 거짓 

 

67-65 = 2

 

53-48=5

 

65+1=66

 

65+1=66 (A 다음의 문자 B가 된다) ' '가없으므로 문자로 출력한다

 

++c은 전열 연산자로 이번 연산에 1을 추가한다 따라서 65+1=66

 

c++은 후열 연산자로 다음 연산에 1을 추가한다 따라서 65

 

위 연산에서 후열 연산자를 사용했으므로 65+1=66 

 

 

 

3-2 아래의 코드는 사과를 담는데 필요한 바구니(버켓)의 수를 구하는 코드이다. 만일 사과의 수가 123개이고 하나의 바구니에는 10개의 사과를 담을 수 있다면, 13개의 바구니가 필요할 것이다. (1)에 알맞은 코드를 넣으시오.

public class Exercise3_2 {
	public static void main(String[] args) {
		int numOfApples = 123; // 사과의 개수
		int sizeOfBucket = 10; // 바구니의 크기(바구니에 담을 수 있는 사과의 개수)
		int numOfBucket = ( /* (1) */ ); // 모든 사과를 담는데 필요한 바구니의 수


		System.out.println("필요한 바구니의 수 :"+numOfBucket1);	//?
		}
}
int numOfBucket =
numOfApples/sizeOfBucket + (numOfApples%sizeOfBucket > 0 ? 1 : 0) ;

풀이 1 사과의 수/바구니 크기 + (사과의 수/나머지가 0이 아니면 1)

int numOfBucket = 
((numOfApples-1)/sizeOfBucket)+1;

풀이 2 (사과의 수 -1) 사과의 수는 어차피 자연수이므로 일의 자리 숫자가 0으로 끝나면 이 식으로 필요한 개수가 출력이 된다.

int numOfBucket1 =
(int)Math.ceil((float)numOfApples / sizeOfBucket);

풀이 3 Math.ceil함수를 사용해서 올림 해서 123/10을 12.3으로 계산한 뒤 13으로 올림 해서 출력한다.

필요한 바구니의 수 :13

결과(공통)

 

 

3-3 아래는 변수 num의 값에 따라 ‘양수’, ‘음수’, ‘0’을 출력하는 코드이다. 삼항 연산자를 이용해서 (1)에 알맞은 코드를 넣으시오.

public class Exercise3_3 {
	public static void main(String[] args) {
		int num = 10;
		System.out.println(/* (1) */);
	}
}
num > 0 ? "양수" : (num < 0 ? "음수" : "0")

(조건식)? (참일 시 실행) : (거짓일 때 실행)

양수

 

 

3-4 아래는 변수 num의 값 중에서 백의 자리 이하를 버리는 코드이다. 만일 변수 num의 값이 ‘456’이라면 ‘400’이 되고, ‘111’이라면 ‘100’이 된다. (1)에 알맞은 코드를 넣으시오.

public class Exercise3_4 {
	public static void main(String[] args) {
		int num = 456;
		System.out.println( /* (1) */ );
	}
}
num/100 * 100

456을 100으로 나누면 소수점은 int타입이라 없어지므로 4가 되고 거기서 다시 100을 곱한다.

400

 

public class Exercise3_4_1 {
	public static void main(String[] args) {
		double num1 = 456;
		double a= Math.floor(num1/100)*100;
		System.out.println(a);
	}
}
400.0

double타입일때 계산법 내림 함수를 이용한다.

 

 

 

3-5 아래는 변수 num의 값 중에서 일의 자리를 1로 바꾸는 코드이다. 만일 변수 num의 값이 333이라면 331이 되고, 777이라면 771이 된다. (1)에 알맞은 코드를 넣으시오.

public class Exercise3_5 {
	public static void main(String[] args) {
		int num = 333;
		System.out.println( /* (1) */ );
	}
}
num/10*10+1

1의 자리를 버리고 1을 더한다.

331

 

public class Exercise3_5_1 {
	public static void main(String[] args) {
		double num1 = 333;
		double n1 = Math.floor(num1/10)*10+1;
		System.out.println( n1 );
	}
}

내림함수를 사용한다.

331.0

 

 

3-6 아래는 변수 num의 값보다 크면서도 가장 가까운 10의 배수에서 변수 num의 값을 뺀 나머지를 구하는 코드이다. 예를 들어, 24의 크면서도 가장 가까운 10의 배수는 30이다. 19의 경우 20이고, 81의 경우 90이 된다. 30에서 24를 뺀 나머지는 6이기 때문에 변수 num의 값이 24라면 6을 결과로 얻어야 한다. (1)에 알맞은 코드를 넣으시오.
[Hint] 나머지 연산자를 사용하라.

public class Exercise3_6 {
	public static void main(String[] args) {
		int num = 24;
		System.out.println((/* (1) */);
	}
}
(num / 10 + 1) * 10 - num)

(1의자리 버림 연산+10)-24

6

 

		System.out.println(10 - (num % 10));

10에서 나머지를 빼버림

6

 

public class Exercise3_6_1 {
	public static void main(String[] args) {
		double num = 24;
		System.out.println((Math.floor(num / 10+1) * 10 - num));
	}
}

함수 사용

6.0

 

 

3-7 아래는 화씨(Fahrenheit)를 섭씨(Celcius)로 변환하는 코드이다. 변환 공식이 'C = 5/9 ×(F - 32)'라고 할 때, (1)에 알맞은 코드를 넣으시오. 단, 변환 결괏값은 소수점 셋째 자리에서 반올림해야 한다.

(Math.round()를 사용하지 않고 처리할 것)

public class Exercise3_7 {
	public static void main(String[] args) {
		int fahrenheit = 100;
		float celcius = ( /* (1) */ );
		System.out.println("Fahrenheit:" + fahrenheit);
		System.out.println(String.format("%.2f", celcius));
	}
}
(int)((5/9f * (fahrenheit - 32))*100 + 0.5) / 100f;

인트의 버림을 이용함

float celcius = 5 / 9f * (fahrenheit - 32);
Fahrenheit:100
37.78

 

 

3-8 아래 코드의 문제점을 수정해서 실행결과와 같은 결과를 얻도록 하시오.

public 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 = 3f / 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);
	}
}
public class Exercise3_8 {
	public static void main(String[] args) {
		byte a = 10;
		byte b = 20;
		byte c = (byte) (a + b);
		char ch = 'A';
		ch = (char) (ch + 2);
		float f = 3f / 2;
		long l = 3000L * 3000 * 3000;
		float f2 = 0.1f;
		double d = 0.1f;
		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);
	}
}

계산은 int형으로 계산하므로 앞에 형 변환을 해줘야 한다.

float이나 long타입으로 계산하고 싶다면 f나 L을 붙여줘야 한다.

double과 float는 부동소수 형태를 받아야 데이터 손실이 나지 않는다.

c=30
ch=C
f=1.5
l=27000000000
result=true

 

3-9 다음은 문자형 변수 ch가 영문자(대문자 또는 소문자)이거나 숫자일 때만 변수 b의 값이 true가 되도록 하는 코드이다. (1)에 알맞은 코드를 넣으시오.

public class Exercise3_9 {
	public static void main(String[] args) {
		char ch = 'z';
		boolean b = (/* (1) */);
	}
}
(ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
true

 

3-10 다음은 대문자를 소문자로 변경하는 코드인데, 문자 ch에 저장된 문자가 대문자인 경우에만 소문자로 변경한다. 문자코드는 소문자가 대문자보다 32만큼 더 크다. 예를 들어 'A‘의 코드는 65이고 ’a'의 코드는 97이다. (1)~(2)에 알맞은 코드를 넣으시오.

public 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);

	}
}
(ch >= 'A' && ch <= 'Z') ? (lowerCase = (char)( ch + 32)) : ch;
ch:A
ch to lowerCase:a

조건 연산자? :

조건 연산자는 조건식, 식 1, 식 2 모두 세 개의 피연산자를 필요로 하는 삼항 연산자이며,

삼항 연산자는 조건 연산자 하나뿐이다.

 

(조건식)? (참이면 반환) : (거짓이면 반환)

 

public class OperatorEx32 {
	public static void main(String[] args) {
		int x, y, z;
		int absX, absY, absZ;
		char signX, signY, signZ;
		
		x = 10;
		y = -5;
		z = 0;
		
		absX = x >= 0 ? x : -x; // x의 값이 음수이면, 양수로 만든다.
		absY = y >= 0 ? y : -y;
		absZ = z >= 0 ? z : -z;
		
		signX = x > 0 ? '+' : (x==0 ? ' ' : '-'); //조건 연산자를 중첩
		signY = y > 0 ? '+' : (y==0 ? ' ' : '-');
		signZ = z > 0 ? '+' : (z==0 ? ' ' : '-'); 
		
		System.out.printf("x=%c%d%n", signX, absX);
		System.out.printf("y=%c%d%n", signY, absY);
		System.out.printf("z=%c%d%n", signZ, absZ);
		
	}

}
x=+10
y=-5
z= 0

 

대입 연산자 = op=

대입 연산자는 변수와 같은 저장공간에 값 또는 수식의 연산 결과를 저장하는 데 사용된다.

특이한 점은 연산 진행방향이 오른쪽에서 왼쪽이다.

대입 연산자의 왼쪽 피연산자를 lvalue(left value)이라 하고, 오른쪽 피연산자를'rvalue(right value)라고 한다.

 

복합 대입 연산자

대입 연산자는 다른 연산자(op)와 결합하여 op=과 같은 방식으로 사용될 수 있다.

 

op= =
i +=3; i = i + 3;
i -= 3; i = i - 3;
i *= 3; i = i * 3;
i /= 3; i = i / 3;
i %= 3; i = i % 3;
i <<= 3; i = i << 3;
i >>= 3; i = i >> 3;
i &= 3; i = i & 3;
i ^= 3; i = i ^ 3;
i |= 3; i = i | 3;

비트 연산자(bitwise operator)

비트 연산자는 피연산자를 비트단위로 논리 연산한다. 

그런데 쓸 일이 거의 없으니 그냥 교양 정도로 보면 된다.

|(OR연산자) 피연산자 중 한 쪽의 값이 1이면, 1을 결과로 얻는다. 그 외에는 0을 얻는다.
&(AND연산자) 피연산자 양 쪽이 모두 1이어야만 1을 결과로 얻는다. 그 외에는 0을 얻는다.
^(XOR연산자) 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.
x y x|y x&y x^y
1 1 1 1 0
1 0 1 0 1
0 1 1 0 1
0 0 0 0 0

연산자 ^는 배타적 XOR(eXclusive OR)라고 하며, 피연산자의 값이 서로 다른 경우, 즉 배타적인 경우에만 참(1)을 결과로 얻는다.

 

비트 연산자    
0xAB | 0xF = 0xAF
1 0 1 0 1 0 1 1
|)        0 0 0 0 1 1 1 1

0xAB
0xF
1 0 1 0 1 1 1 1 0xAF

|(OR)는 주로 특정 비트의 값을 변경할 때 사용한다.

 

 

비트 연산자    
0xAB & 0xF = 0xB
1 0 1 0 1 0 1 1
&)     0 0 0 0 1 1 1 1
0xAB
0xF
0 0 0 0 1 0 1 1 0xB

&(AND)는 주로 특정 비트의 값을 뽑아낼 때 사용한다.

 

 

비트 연산자    
0xA4 ^ 0xF = 0xAB
1 0 1 0 0 1 0 0
 ^)    0 0 0 0 1 1 1 1
0xA4
0xF
1 0 1 0 1 0 1 1 0xAB

^(XOR)는 두 피연산자의 비트가 다를 때만 1이 된다.

 

 

비트 전환 연산자 ~

x ~x
1 0
0 1

~는 주로 특정 비트의 값을 뽑아낼 때 사용한다.

주의할 점은 비트 연산자 '~'에 의해 '비트 전환'되고 나면, 부호가 있는 타입의 피연산자는 부호가 반대로 변경된다.

 

쉬프트 연산자 << >>

이 연산자는 피연산자의 각 자리를 이동한다고해서 쉬프트 연산자(shift operator)라고 이름 붙여졌다.

 

10진수 8은 2진수로표현한 뒤 쉬프트 연산자를 적용하면,

 

  << >>
연산전 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0
연산후 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0

각 각 연산 후 8이 16과 4가 되었다.

또한 쉬프트 연산자의 범위를 벗어난 값은 버려지고, 0이 된다. 이로써 알 수 있는 것은

x << n은 x * 2ⁿ의 결과와 같다.

x >> n은 x / 2ⁿ의 결과와 같다.

논리 연산자(logical operator)

&&(and), ||(or),!(not)

 

&&(AND결합) 피연산자 양쪽 모두 true여야 true를 결과로 얻는다.
||(or결합) 피연산자 중 어느 한 쪽만 true면 true를 결과로 얻는다.

논리 연산자의 피연산자가 참인 경우와 거짓인 경우의 연산 결과를 표(truth table)로나타내면 다음과 같다.

 

x y x||y x&&y
true true true true
true false true false
false true true false
false false false false

 

사용 시 주의해야 할 점을 알아보자

 

 

public class OperatorEx24_0 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
		
		x = 15;
		System.out.printf("x=%2d, 10 < x && x < 20 = %b%n", x, 10 < x && x < 20);
        
        }
}
x=15, 10 < x && x < 20 = true

 

x=15

&&는 10 < x과 x <20을 만족해야 true > (boolean) true

 

 

public class OperatorEx24_1 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
		
        		x = 6;
		System.out.printf("x=%2d , x%%2==0 || x%%3==0 && x%%6!=0 = %b%n",x, x%2==0 || x%3==0&&x%6!=0);
		System.out.printf("x=%2d , (x%%2==0 || x%%3==0) && x%%6!=0 = %b%n",x, (x%2==0 || x%3==0)&&x%6!=0);
		}

}
x= 6 , x%2==0 || x%3==0 && x%6!=0 = true
x= 6 , (x%2==0 || x%3==0) && x%6!=0 = false

 

x=6

(X가 3의 배수이고(&&) X가 6의 배수가 아니면 참)이거나(||) X가 2의 배수(x%2==0)

거짓 이거나(||) X가 이의 배수 = 참

&&가(AND) 곱셈 연산자이고 ||(OR)이 덧셈 연산자라 &&가 ||보다 계산이 빠름

 

X가 2의 배수(x%2==0) 거나(||) X가 3의 배수이고(&&) X가 6의 배수가 아니면 참= 참

 

 

public class OperatorEx24_2 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
				ch='1';
		System.out.printf("ch='%c', '0' <= ch && ch <= '9' =%b%n", ch, '0' <= ch && ch <='9');
      	}

}
ch='1', '0' <= ch && ch <= '9' =true

 

ch는 1 == char 타입 46

45 <=ch <=54가 참이므로 true

 

 

public class OperatorEx24_3 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
				ch='a';
		System.out.printf("ch='%c', 'a' <= ch && ch <= 'z' =%b%n", ch, 'a' <= ch && ch <='z');
		}

}
ch='a', 'a' <= ch && ch <= 'z' =true

 

ch = 'a' = char타입 97

a <=a <=z 즉 참

 

 

public class OperatorEx24_4 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
				ch='A';
		System.out.printf("ch='%c', 'A' <= ch && ch <= 'Z' =%b%n", ch, 'A' <= ch && ch <='Z');
       	}

}
ch='A', 'A' <= ch && ch <= 'Z' =true

 

ch = 'A' = char타입 65

A <=A <=Z 즉 참

 

 

public class OperatorEx24_5 {
	public static void main(String[] args) {
		int x = 0;
		char ch = ' ';
        		ch='q';
		System.out.printf("ch='%c', 'q' <= ch && ch <= 'Q' =%b%n", ch, 'q' <= ch && ch <='Q');
        }
}
ch='q', 'q' <= ch && ch <= 'Q' =false

 

ch = 'q' = char 타입 113

'q' <= 'q'이고(&&) 'q'(113) <= 'Q'(71) = 거짓

 

 

효율적인 연산(short circuit evaluation)

논리 연산자의 또 다른 특징은 효율적인 연산을 한다는 것이다.

 

x y x||y
true false true
true false true
false true false
false false false

x가 true면 그대로 연산 종료

 

x y x&&y
true false true
true false true
false true false
false false false

x가 false면 그대로 연산 종료

 

 

논리 부정 연산자

!

이 연산자는 피연산자가 true이면 false를, false이면 true를 결과로 반환하는 연산자이다.

 

x !x
true false
false true

어떤 값에 논리연산자를 중복으로 적용하면 참과 거짓이 차례로반복된다. a가 참이면

!!!!a의 경우 

!!! + !a(거짓)

!! !a'(참)

! !a''(거짓)

!a'''(참)

최종 a=참이 된다.

비교 연산자는 두 피 연산자를 비교하는데 사용되는 연산자다.

연산 결과는 boolean타입인 true와 false로 출력된다.

 

대소 비교 연산자 <, >, <=, >=

boolean과 참조형을 제외한 나머지에 다 사용 가능한 연산자이다.

비교연산자 연산결과
> 좌변 값이 크면, true 아니면 false
< 좌변 값이 작으면 true 아니면 false
>= 좌변값이 크거나 같으면 true 아니면false
<= 좌변 값이 작거나 같으면 true 아니면 false

주의할 점은 <=와 >=의 연산자는 순서를 틀리면 안 된다는 점이다.

 

등가 비교 연산자

두 피연산자의 값이 같은지 또는 다른지를 비교하는 연산자이다.

 

비교 연산자도  
   
   

 

public class OperatorEX22 {
	public static void main(String[] args) {
		float f = 0.1f;
		double d = 0.1;
		double d2 = (double) f;

		System.out.printf("10.0==10.0f	%b%n ", 10.0 == 10.0f);
		System.out.printf("0.1==0.1f	%b%n ", 0.1 == 0.1f);
		System.out.printf("f=%19.17f%n ", f);
		System.out.printf("d =%19.17f%n ", d);
		System.out.printf("d2=%19.17f%n ", d2);
		System.out.printf("d==f %b%n ", d == f);
		System.out.printf("d==d2 %b%n ", d == d2);
		System.out.printf("d2==f %b%n ", d2 == f);
		System.out.printf("(float)d==f %b%n ", (float) d == f);
	}
}
10.0==10.0f	true
 0.1==0.1f	false
 f=0.10000000149011612
 d =0.10000000000000000
 d2=0.10000000149011612
 d==f false
 d==d2 false
 d2==f true
 (float)d==f true

이항 연산자이므로 연산을 수행하기 전에 형 변환을 통해 두 피연산자의 타입을 같게 맞춘 다음 피연산자를 비교한다.

 

문자열의 비교

두 문자열을 비교할 때는, 비교 연산자'=='대신 equals()라는 메서드를 사용해야 한다.\비교 연산자는 두 문자열이 완전히 같은 것인지 비교할 뿐이므로, 문자열의 내용이 같은지 비교하기 위해서는 equals()를 사용하는 것이다.

public class OperatorEx23_ {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = new String("abc");
		

		System.out.printf("\"abc\"==\"abc\" ? %b%n", "abc"=="abc");
		System.out.printf(" str1==\"abc\" ? %b%n", str1=="abc");
		System.out.printf(" str1==\"abc\" ? %b%n", str2=="abc");
		System.out.printf("str1.equals(\"abc\") ? %b%n", str1.equals("abc"));
		System.out.printf("str2.equals(\"abc\") ? %b%n", str2.equals("abc"));
		System.out.printf("str2.equalsIgnotreCase(\"abc\") ? %b%n", str2.equalsIgnoreCase("abc"));
	}
}
"abc"=="abc" ? true
 str1=="abc" ? true
 str1=="abc" ? false
str1.equals("abc") ? true
str2.equals("abc") ? true
str2.equalsIgnotreCase("abc") ? true

str2와 'abc'의 내용이 같아도 false를 얻는다. 내용이 같지만 서로 다른 객체라서 그렇다.

 

산술 연산자

사칙 연산자는 덧셈(+) 뺄셈(-) 곱셈(*) 나눗셈(/)이다.

주의할 점은 나누기 연산자를 할 때 피연산자가 둘 다 int타입인 경우 소수점을 저장하지 못하므로 정수만 남고 소수점 이하는 버려지며, 반올림도 발생하지 않는다.

public class OperatorEx05 {
	public static void main(String[] args) {
		int a = 10;
		int b = 4;
        
		System.out.printf("%d + %d = %d%n", a, b, a + b);
		System.out.printf("%d - %d = %d%n", a, b, a - b);
		System.out.printf("%d * %d = %d%n", a, b, a * b);
		System.out.printf("%d / %d = %d%n", a, b, a / b);
		System.out.printf("%d / %f = %f%n", a, (float) b, a / (float) b);
	}
}
10 + 4 = 14
10 - 4 = 6
10 * 4 = 40
10 / 4 = 2
10 / 4.000000 = 2.500000

 

 

 

x y x/y x%y
유한수 +-0.0 +-Infinity NaN
유한수 +-Infinity +-0.0 x
+-0.0 +-0.0 NaN NaN
+-Infinity 유한수 +-Infinity NaN
+-Infinity +-Infinity NaN NaN

피연산자가 유한수가 아닐 경우 연산 결과이다.

기본적으로 올바른 연산 결과를 얻기 위해서는 수치가 큰 쪽으로 형 변환하며, 만약 크기가 작다면 int형으로 자동으로 변환되어 계산된다.

또한 기존에 변수를 byte로 정의하더라도, 산술 연산자로 연산을 하면 int로 자동 형 변환(rype conversion, casting)이 되어 계산이 된다.

그리고 큰 자료형에서 작은 자료형으로 변환하거나 논리형이 다르면 데이터 손실이 발생하므로 

같은 논리형의 동일한 크기의 자료 혹은 같은 논리형의 큰 크기의 자료형으로 변경해야 데이터 손실이 적거나 없다.

 

또한 자료형의 범위를 넘어가면 오버플로우나 언더플로우가 발생한다.

 

그리고 일반적인 사칙연산과 다르게 자바 프로그램의 사칙연산은 숫자뿐 아니라 문자로도 사칙연산이 가능하다.

이는 문자가 실제로 문자 그대로 저장되는 것이 아니라 해당 문자의 유니코드로 바뀌어 저장되기 때문이다.

만약 문자에 해당하는 숫자를 보고 싶다면 ch타입의 문자를 int형태로 형 변환하면 된다.

 

문자 코드 문자 코드 문자 코드
0 48 A 65 a 97
1 49 B 66 b 98
2 50 C 67 c 99
3 51 D 68 d 100
4 52 E 69 e 101
5 53 ... ... ... ...
6 54 X 88 x 120
7 55 Y 89 y 121
8 56 Z 90 z 122

숫자랑 문자는 연속적으로 되어있는데 특이하게 영문의 경우 대문자 소문자의 시작 코드 사이에 다른 문자가 있으니 문자 형태로 계산할 시 조심하자. 소문자 a에서 대문자 A를 빼면 32의 값이 차이가 나며 대문자, 소문자, 숫자의 시작 코드와 소문자와 대문자의 코드의 차가 32라는것을 알아두면 좋다.

public class OperatorEx12 {
	public static void main(String[] args) {
		
		char c1 = 'a';	// c1에는 문자 'a'의 코드값인 97이 저장된다.
		char c2 = c1;	// c1에 저장되어 있는 값이 c2에 저장된다.
		char c3 = ' ';	// c3를 공백으로 초기화 한다.
		
		int i = c1 + 1;	// 'a'+1 > 97+1 > 98
		
		c3 = (char)(c1 + 1);	// c1 + 1의 형태가 int 이므로 char로 변환
		c2++;
		c2++;
		
		System.out.println("i=" + i);
		System.out.println("c2=" + c2);
		System.out.println("c3=" + c3);
	}
}
i=98
c2=c
c3=b

c1+1은 int로 바꾼'a'+1=97+1=98이 되어 저장된다,

c2는 형변환 없이 c2에 에 저장된 값에 +2가 되므로 (char)99='c'가되는 것이다.

보통 일부러 뻔한 리터럴 연산을 풀어 쓸 필요가없이 답을 적으면 되지만, 가독성 때문에 그렇게 하는 경우가있다.

예를들어 86400이라는 숫자는 무엇을 의미하는지 선뜻 이해하기 어려울 수 있지만 이것을 60*60*24로 쓰면 초, 분, 시 를곱한값으로 이해하기 쉬워진다. 이렇게 써도 컴파일러에 의해 미리 계산되기 때문에 성능 차이는없다.

 

public class OperatorEx17 {
	public static void main(String[] args) {
		double pi = 3.141592;
		double shortPi = (int)(pi * 1000 + 0.5) / 1000.0;
		System.out.println(shortPi);
	
}
3.142

나눗셈의 경우 주의할 점이 있는데 double타입으로 정의한 변수를 나눈다 하더라도 위의 경우 int형으로 계산이 되며 나머지는 버려진다는 점이다. 반면에 이런 특징을 이용해서 식으로 반올림을 할 수 있다.

증감 연산자(increment operator)

증감 연산자는 피연산자에 저장된 값을 1 증가 또는 감소시킨다.

증가 연산자(++) 피연산자의 값을 1 증가시킨다.
감소 연산자(--) 피연산자의 값을 1 감소시킨다.

일반적으로 단항 연산자는 피연산자의 왼쪽에 위치하지만 증가 연산자'++'와 감소 연산자'--'는 양쪽 모두 가능한다.

피연산자의 왼쪽에 위치하면 '전위형(prefix)', 오른쪽에 위치하면 '후위형(postfix)'이라고 한다.

전위형은 후위형은 얼핏 보기에 같은 연산자처럼 보이지만 차이점이 있다.

 

public class OperatorEx02 {
	public static void main(String[] args) {
		int i = 5, j = 0;

		j = i++;
		System.out.println("j=i++; 실행 후, i=" + i + ", j=" + j);

		i = 5; // 결과를 비교하기 위해, i와 j의 값을 다시 5와 0으로 변경
		j = 0;

		j = ++i;
		System.out.println("j=++i; 실행 후, i=" + i + ", j=" + j);
	}

}
j=i++; 실행 후, i=6, j=5
j=++i; 실행 후, i=6, j=6

실행결과를 보면 i의 값은 두 경우 모두 1이 증가되어 6이 되지만, j의 값을 그렇지 않다.

따라서 코드를 짤 때 증감 연산자의 방식을 한 가지로 통일해서 짜는 쪽이 좋다.

 

부호 연산자 + -

부호 연산자'-'는 피연산자의 부호를 반대로 변경한 결과를 반환한다.

부호 연산자'+'는 거의 쓸 일이 없다.

+ Recent posts