연산자와 연산식
- 프로그램에서 데이터를 처리하여 결과를 산출하는 것은 연산(operations)라고 함
- 연산에 사용되는 표시나 기호를 연산자(operator)라고 함
- 연산되는 데이터는 피연산자(operand)라고 함
- 연산자와 피연산자를 이용하여 연산의 과정을 기술하는 것은 연산식(expressions)라고 함
- +, -, *, == 은 연산자
- x, y, z 변수는 피연산자
- 연산자는 필요로 하는 피연산자의 수에 따라 단항, 이항, 삼항 연산자로 구분
단항 연산자: ++x;
이항 연산자: x + y;
삼항 연산자: (sum>90) ? "A" : "B";
연산의 방향과 우선순위
- ( )
- * / %
- + -
- 우선순위가 같은 연산자의 순서 - p.67 참고
100 * 2 / 3 % 5
* / % 같은 우선순위를 갖고 있음
방향이 왼쪽에서 오른쪽으로 수행
> 대부분은 왼쪽에서 오른쪽으로 연산 시작
a = b = c = 5;
> 단항 연산자(++, --, ~, !), 부호 연산자(+, -), 대입 연산자(=, +=, -+, ...)은 오른쪽에서 왼쪽으로 연산됨
* 우선순위
1. 단항, 이항, 삼항 순
2. 산술, 비교, 논리, 대입 연산자 순
3. 단항과 대입 연사자를 제외한 모든 연산의 방향은 왼->오
4. 복잡한 연산식에는 괄호()를 사용해서 우선순위 정함
단항 연산자
- 피연산자가 단 하나뿐인 연산자를 말함
- 부호 연산자(+, -), 증감 연산자(++, --), 논리 부정 연산자(!), 비트 반전 연산자(~)
부호 연산자(+, -)
- 부호 연산자의 산출 타입은 int 타입이 된다
package thisisjava.chap03.num01;
public class SignOperatorExample {
public static void main(String[] args) {
int x = -100;
int result1 = +x;
int result2 = -x;
System.out.println("result1=" + result1);
System.out.println("result2=" + result2);
short s = 100;
// short result3 = -s; //컴파일 에러
int result3 = -s;
System.out.println("result3=" + result3);
}
}
> short ㄴㄴ int ㅇㅋ
증감 연산자 (++, --)
- ++ 1 증가, -- 1 감소
- ++ 피연산자: 다른 연산을 수행하기 전에 피연산자의 값을 1 증가시킴
- -- 피연산자: 다른 연산을 수행하기 전에 피연산자의 값을 1 감소시킴
- 피연산자 ++: 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킴
- 피연산자 --: 다른 연산을 수행한 후에 피연산자의 값을 1 감소시킴
package thisisjava.chap03.num01;
public class IncreaseDecreaseOperatorExample {
public static void main(String[] args) {
int x = 10;
int y = 10;
int z;
System.out.println("----------");
x++; //11
++x; //12
System.out.println("x=" + x); //12
System.out.println("----------");
y--; //9
--y; //8
System.out.println("y=" + y); //8
System.out.println("----------");
z = x++; //12 //13
System.out.println("z=" + z); //12
System.out.println("x=" + x); //13
System.out.println("----------");
z = ++x; //14
System.out.println("z=" + z); //14
System.out.println("x=" + x); //14
System.out.println("----------");
z = ++x + y++; // 15+8
System.out.println("z=" + z); //23
System.out.println("x=" + x); //15
System.out.println("y=" + y); //9
}
}
논리 부정 연산자(!)
- true를 flase로, false를 true로 변경
- boolean 타입에만 사용할 수 있음
! 피연산자
피연산자가 true이면 false 값 산출
피연산자가 false이면 true 값 산출
package thisisjava.chap03.num01;
public class DenyLogicOperatorExample {
public static void main(String[] args) {
boolean play = true;
System.out.println(play);
play = !play;
System.out.println(play);
play = !play;
System.out.println(play);
}
}
비트 반전 연산자(~)
- 정수타입의 피연산자에만 사용
- 피연산자를 2진수로 표현했을 때 비트값인 0을 1로, 1은 0으로 반전
- 부호가 반대인 새로운 값이 산출
- 산출 타입은 int 타입
package thisisjava.chap03.num01;
public class BitReverseOperatorExample {
public static void main(String[] args) {
int v1 = 10;
int v2 = ~v1;
int v3 = ~v1 + 1;
System.out.println(toBinaryString(v1) + "(십진수: " + v1 + ")");
System.out.println(toBinaryString(v2) + "(십진수: " + v2 + ")");
System.out.println(toBinaryString(v3) + "(십진수: " + v3 + ")");
System.out.println();
int v4 = -10;
int v5 = ~v4;
int v6 = ~v4 + 1;
System.out.println(toBinaryString(v4) + "(십진수: " + v4 + ")");
System.out.println(toBinaryString(v5) + "(십진수: " + v5 + ")");
System.out.println(toBinaryString(v6) + "(십진수: " + v6 + ")");
}
public static String toBinaryString(int value) {
String str = Integer.toBinaryString(value);
while (str.length() < 32) {
str = "0" + str;
}
return str;
}
}
이항 연산자
- 피연산자가 두 개인 연산자를 말함
- 산술 연산자, 문자열 연결 연산자, 대입 연산자, 비교 연산자, 논리 연산자, 비트 논리 연산자, 비트 이동 연산자 등
산술 연산자 (+, -, *, /, %)
- boolean 타입을 제외한 모든 기본 타입에 사용할 수 있음
int result = num % 3;
0, 1, 2 중의 한 값
num을 3으로 나눈 나머지
- 피연산자들이 모두 정수 타입이고, int 타입보다 크기가 작은 타입의 경우 모두 int 타입으로 변환 후 연산 수행
연산의 산출 타입은 int
byte + byte -> int + int = int - 피연산자들이 모두 정수타입이고, long 타입이 있을 경우 모두 long 타입으로 변환 후 연산 수행
연산의 산출 타입은 long
int + long -> long + long = long - 피연산자 중 실수 타입(float, double)이 있을 경우, 크기가 큰 실수 타입으로 변환 후 연산 수행
연산의 산출 타입은 실수 타입
int + double -> double + double = double - long을 제외한 정수 타입 연산은 int 타입으로 산출, 피연산자 중 하나라도 실수 타입이면 실수 타입으로 산출
package thisisjava.chap03.num01;
public class ArithmeticOperatorExample {
public static void main(String[] args) {
int v1 = 5;
int v2 = 2;
int result1 = v1 + v2;
int result2 = v1 - v2;
int result3 = v1 * v2;
int result4 = v1 / v2;
int result5 = v1 % v2;
double result6 = (double) v1 / v2;
System.out.println("resutl1=" + result1);
System.out.println("resutl2=" + result2);
System.out.println("resutl3=" + result3);
System.out.println("resutl4=" + result4);
System.out.println("resutl5=" + result5);
System.out.println("resutl6=" + result6);
}
}
> 산술 연산자
package thisisjava.chap03.num01;
public class CharOperationExample {
public static void main(String[] args) {
char c1 = 'A' + 1;
char c2 = 'A';
// char c3 = c2 +1; //컴파일 에러
char c3 = (char) (c2 + 1); //캐스팅
System.out.println("c1: " + c1);
System.out.println("c2: " + c2);
System.out.println("c3: " + c3);
}
}
> char 타입이 산술 연산이 될 경우 int 타입으로 변환, 산출 타입은 int 타입
오버플로우
- 산출 타입으로 표현할 수 없는 값이 산출되었을 경우, 오버플로우가 발생
쓰레기값(엉뚱한 값)을 얻을 수 있음
package thisisjava.chap03.num01;
public class OverflowExample {
public static void main(String[] args) {
int x = 1000000;
int y = 1000000;
int z = x * y;
System.out.println(z);
}
}
> int 타입에 저장될 수 있는 값의 범위를 초과
> 그래서 쓰레기값을 얻게 됨
> 변수 x와 y 중 최소 하나라도 long 타입이 되어야 하고, 변수 z가 long 타입이어야 함
package thisisjava.chap03.num01;
public class OverflowExample1 {
public static void main(String[] args) {
long x = 1000000;
long y = 1000000;
long z = x + y;
System.out.println(z);
}
}
> 오버플로우 해결
정확한 계산은 정수 사용
package thisisjava.chap03.num01;
public class CheckOverflowExample {
public static void main(String[] args) {
try {
int result = safeAdd(2000000000, 2000000000);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("오버플로우가 발생하여 정확하게 계산할 수 없음");
}
}
public static int safeAdd(int left, int right) {
if (right > 0) {
if (left > (Integer.MAX_VALUE - right)) {
throw new ArithmeticException("오버플로우 발생");
}
} else {
if (left < (Integer.MIN_VALUE - right)) {
throw new ArithmeticException("오버플로우 발생");
}
}
return left + right;
}
}
package thisisjava.chap03.num01;
public class AccuracyExample1 {
public static void main(String[] args) {
int apple = 1;
double pieceUnit = 0.1;
int number = 7;
double result = apple - number * pieceUnit;
System.out.println("사과 한개에서 ");
System.out.println("0.7 조각을 빼면, ");
System.out.println(result + "조각이 남는다");
}
}
> 정확하게 계산할 때에는 부동소수점 타입을 사용하지 않는다
package thisisjava.chap03.num01;
public class AccuracyExample2 {
public static void main(String[] args) {
int apple = 1;
int totalPieces = apple * 10;
int number = 7;
int temp = totalPieces - number;
double result = temp / 10.0;
System.out.println("사과 한개에서 ");
System.out.println("0.7 조각을 빼면, ");
System.out.println(result + " 조각이 남는다");
}
}
> 정확하게 계산할 때는 정수 연산 사용
NaN과 Infinity 연산
package thisisjava.chap03.num01;
public class InfinityAndNaNCheckExample {
public static void main(String[] args) {
int x = 5;
double y = 0.0;
double z = x / y;
double k = x % y;
System.out.println("z: " + Double.isInfinite(z));
System.out.println("k: " + Double.isInfinite(k));
System.out.println("z: " + Double.isNaN(z));
System.out.println("k: " + Double.isNaN(k));
System.out.println("z: " + z + 2);// /는 infinity
System.out.println("y: " + k + 2); // %는 NaN
}
}
> /는 infinity , %는 NaN
> 연산의 결과가 Infinity 또는 NaN이면 절대로 다음 연산을 수행하지 못하도록 if문을 ㅏ용해서 실행 흐름을 변경함
입력값의 NaN 검사
package thisisjava.chap03.num01;
public class InputDataCheckNaNExample1 {
public static void main(String[] args) {
String userInput = "NaN";
double val = Double.valueOf(userInput);
double currentBalcne = 10000.0;
currentBalcne += val;
System.out.println(currentBalcne);
}
}
> NaN은 산술 연산이 가능하다는 점이 문제
> 사용자로부터 문자열을 입력받을 때에는 반드시 "NaN"인지 조사함
> 만약 "NaN"이라면 NaN과 산술 연산을 수행해서는 안 된다
package thisisjava.chap03.num01;
public class InputDataCheckNaNExample2 {
public static void main(String[] args) {
String userInput = "NaN";
double val = Double.valueOf(userInput);
double currentBalance = 10000.0;
if (Double.isNaN(val)) {
System.out.println("NaN이 입력되어 치리할 수 없음");
val = 0.0;
}
currentBalance += val;
System.out.println(currentBalance);
}
}
> NaN인지 검사를 하려면 반드시 Double.isNaN()을 사용해야 함
'이것이 자바다' 공부 기록
300x250
'Language > JAVA' 카테고리의 다른 글
[JAVA] 조건문 // if문 switch문 (0) | 2021.09.14 |
---|---|
[JAVA] 연산자와 연산식 2 // 이항연산자 삼항연산자 (0) | 2021.09.13 |
[JAVA] 데이터 타입 변환 // 자동타입변환 강제타입변환 연산식타입변환 (0) | 2021.09.11 |
[JAVA] 데이터 타입 // 정수 실수 문자 논리 (0) | 2021.09.10 |
[JAVA] 변수 (0) | 2021.09.09 |