ex01_op
// 논리부정연산자(!)는 true 또는 false를 부정하는 연산자로서 boolean타입에만
// 사용할 수 있다. 피연산자가 true이면 false, false이면 true를 리턴한다.
// 논리부정연산자는 조건문과 제어문에서 사용되어 조건식의 값을 부정하도록 하여
// 실행흐름을 제어할 때 주로 사용한다.
boolean isPlay = true;
System.out.println("isPlay = " +isPlay);
isPlay = !isPlay;
System.out.println("isPlay = " +isPlay);
isPlay = !isPlay;
System.out.println("isPlay = " +isPlay);
/*
증감연산자(++, --)
증감연산자는 변수의 값을 1씩 증가(++), 1씩 감소(--)를 시키는 연산자를 말한다.
boolean타입을 제외한 모든 기본데이터타입의 피연산자에 사용할 수 있다.
증감연산자는 선언위치에 따라 후위, 전위 증감연산자로 구분이 된다. 변수 앞에
정의된 것을 전위증감연산자, 변수 뒤에 정의된 것을 후위 증감연산자라고 한다.
주의할 점은 다른 연산자와 함께 사용되는 연산식에서는 증감연산자의 위치에 따라
연산결과가 다르게 나오므로 주의해야 한다.
전위연산자는 연산 전에 증감을 시키고 후위연산자는 연산을 한 후에 증감을 시킨다.
*/
ex02_arithmetic
// 정확한 연산을 해야하는 경우 실수타입을 사용하지 않는 것이 좋다.
int apple = 1;
double pieceUnit = 0.1;
int number = 7;
double result = apple - (number * pieceUnit);
System.out.println("남은 사과조각 = " + result);
// 상기결과는 정확하게 0.3이 나와야 하지만 0.29999999999999993이 나온다.
// 이것은 실수의 계산은 이진포맷의 기수(이진법)를 사용하기 때문에 0.1을
// 정확하게 표현할 수 없어 근사치로 처리하기 때문이다.
// 따라서 정확한 계산이 필요한 경우에는 정수연산으로 변경하여 처리해야 한다.
int totalPieces = apple * 10;
int temp = totalPieces - 7;
System.out.println(temp);
result = temp / 10.0;
System.out.println("사과 한개에서 0.7조각을 빼면");
System.out.println(result+"조각이 남습니다");
/*
산술연산자(+,_,*,/,%)
산술연산자는 사칙연산과 나머지를 구하는 연산자*%)를 포함해서 총 5개의 연산자가 있다.
이 연산자는 boolean타입을 제외한 모든 기본 타입에 사용할 수 있다.
산술연산자의 특징은 피연산들의 타입이 동일하지 않을 경우 피연산자들의 타입을 일치시킨후
연산을 수행한다. 타입을 일치 시킬 경우에 아래와 같은 규칙을 가지고 수행한다.
1. 피연산자들이 모두 정수타입이고 int타입보다 크기가 작을경우 모두 int로 형변환한 후에
연산을 수행한다. 따라서 연산의 결과는 int타입이다.
byte + byte -> int + int = 결과는 int 타입이다.
2. 피연산자들이 모두 정수 타입이고 long타입이 있을 경우 모두 long으로 변환 후 연산을 수행한다.
따라서 ,연산의 결과는 long타입이다.
int + long -> long + long = 결과의 타입은
3. 피연산자 중 실수타입(float, double)이 있을 경우 크기가 큰 실수타입으로 변환 후 연산을 수행
따라서, 연산의 결과는 실수이다.
int + double -> double + double = 결과값은 double
정수타입연산은 long을 제외하고 int로 변환후 연산되고 피연산 중 하나라도 실수타입이 있다면
결과는 실수 타입으로 계산된다.
정수타입 연산결과가 int타입으로 나오는 이유는 JVM이 기본적으로 32bite(4byte)단위로 연산을
수행하기 때문이다.
*/
byte byte1 = 1;
byte byte2 = 1;
// byte byte3 = byte1 + byte2; // 형변환을 하지 않을 경우에는 에러
int result1 = byte1 + byte2;
System.out.println("result1=" +result1);
int int1 = 10;
int int2 = 4;
int result2= int1 + int2; // 정수타입의 연산은 기본으로 int타입으로 수행된다.
System.out.println("result2=" +result2);
double result3 = int1 / int2;
System.out.println("result3=" +result3);
System.out.println("===================");
result3 = (int1 / 4.0);
System.out.println("result3=" +result3);
System.out.println("===================");
int v1 = 5;
int v2 = 5;
result1 = v1 + v2;
System.out.println("v1+v2="+result1);
result1 = v1 - v2;
System.out.println("v1-v2="+result1);
result1 = v1 *v2;
System.out.println("v1*v2="+result1);
result1 = v1 / v2;
System.out.println("v1/v2="+result1);
result1 = v1 % v2;
System.out.println("v1%v2="+result1);
// /, %연산을 수행할 떄 주의할 점이 있다.
// 좌측 피연산자가 정수타입인 경우 나누는 수인 우측 피연산자는 0을 사용할 수 없다.
// 0으로 나누는 경우 ArithmeticException 예외가 발생한다.
// 그러나 실수타입인 경우 0.0 or 0.0f로 나누면 예외가 발생되지 않고 나누기 연산의
// 결과 무한대(Infinity)값을 가지고 나머지(%)연산의 결과는 NaN(Not a Number)결과를
// 리턴한다.
// System.out.println(5/0); //ArithmeticException
System.out.println(5/0.0); // Infinity값을 리턴
System.out.println(5 % 0.0); // NaN값을 리턴
// Java에서는 프로그램에서 /, %연산의 결과가 Infinity or NaN인지를 확인하려면
// double.isInfinite(), Double.isNan()메서드를 이용한다.
// 이 메서드는 리턴되는 값이 Infinity or NaN이면 true를 리턴하고 아니면 false를 리턴한다.
int x = 5;
double y = 0.0;
double z1 = x / y;
double z2 = x % y;
System.out.println(Double.isFinite(z1));
System.out.println(Double.isInfinite(z1));
System.out.println(Double.isFinite(z2));
System.out.println(Double.isInfinite(z2));
System.out.println();
System.out.println(Double.isNaN(z1));
System.out.println(Double.isNaN(z2));
System.out.println("z1 + 2 =" +(z1+2));
System.out.println("z2 + 2 =" +(z2+2));
if(Double.isInfinite(z1)||Double.isNaN(z2)) {
System.out.println("계산불가");
}else {
System.out.println("z1 + 2 =" +(z1+2));
System.out.println("z2 + 2 =" +(z2+2));
}
// 산술연산할 때 주의할 점은 연산 후의 값이 데이터타입으로 충분히 표현가능한지
// 여부를 확인해야 한다. 표현할 수 없는 값이 산출될 경우 overflow가 발생되고
// 결과값은 쓰레기값(엉뚱한 값)을 얻을 수가 있다.
int x = 1000000;
int y = 1000000;
int z = x + y;
System.out.println("x + y =" + z);
z = x * y;
System.out.println("x * y =" + z);
// 상기와 같은 에러를 방지하기 위해서는 두 변수 중 하나는 long으로 선언되어야
// 하고 z의 데이터 타입도 long이 되어야 한다.
long x1 = 100000;
long y1 = 100000;
long z1 = x1 * y1;
System.out.println("x1 * y1 =" + z1);
// 문자열 연결연산자(+)
// + 연산자는 산술연산자, 부호연산자인 동시에 문자열 연결연산자이기도 하다.
String str1 = "JDK" + 1.8;
System.out.println(str1);
String str2 = str1 + "특징";
System.out.println(str2);
String str3 = "JDK" + 1.8 + 0.2;
System.out.println(str3);
String str4 = 1.8 + 0.2 + "JDK";
System.out.println(str4);
ex03_compare
// 비교연산자 : <, >, <=, >=, !=
int num1 = 10;
int num2 = 10;
boolean result1 = num1 == num2;
boolean result2 = num1 != num2;
boolean result3 = num1 <= num2;
System.out.println("num1 == num2의 결과는 "+result1);
System.out.println("num1 != num2의 결과는 "+result2);
System.out.println("num1 <= num2의 결과는 "+result3);
System.out.println();
char char1 = 'A';
char char2 = 'B';
boolean result4 = char1 < char2;
System.out.println("char1 < char2의 결과는" +result4);
// 비교연산시에도 연산을 수행하기 전에 혀엽ㄴ환이 발생되어서
// 피연산자의 타입을 일치시킨다.
System.out.println('A'==65); //true
System.out.println(3==3.0); //true
System.out.println(0.1==0.1f); //false
// 이진포맷기수를 사용하는 모든 부동소수점타입은 0.1을 정확히 표현할 수가
// 없기 때문에 true가 아니라 false가 결과값으로 산출된다.
// 0.1f를 double로 형변환을 하면 실제값은 0.10000000149011612이 된다.
System.out.println();
System.out.println(0.1f);
System.out.println((double)0.1f);
// 삼항연산자(조건식 ? true일 경우 : false일 경우)는 세개의 피연산자를 필요로 하는
// 연산자를 말한다. 삼항연산자는 ? 앞의 조건식에 따라 콜론(:) 앞뒤의 피연산자가
// 선택된다고 해서 조건연산식이라고 하기도 한다.
// 사용방법은
// 조건식 ? 값 or 표현식 : 값 or 표현식
int score = 85;
if(score>=90) {
System.out.println("A학점");
}else {
System.out.println("B학점");
}
// 삼항연산식
// (score >= 90) ? System.out.println("A학점") : System.out.println("B학점"); // 에러
char grade = (score>=90) ? 'A':'B';
System.out.println(grade + "학점");
// 논리연산자(&&, &, ||, |, ^, !)
// 논리연산자는 논리곱(&&, &), 논리합(||, |), 배타적 논리합(XOR, ^), 논리부정(!)
// 연산을 수행한다. 논리연산자의 피연산자는 boolean타입만 사용할 수 있다.
// 논리곱연산자인 &&와 &는 산출결과는 같지만 연산과정이 조금 다르다. &&는 앞의
// 피연산자가 false라면 뒤의 연산은 비교하지 않고 false를 리턴하지만 &는 두 피
// 연산자를 모두 비교해서 산출결과를 리턴한다. 따라서 &보다 &&이 더 효율적으로
// 동작한다
// 논리합연산자인 ||와 |도 마찬가지이다. ||는 앞의 연산이 true라면 뒤의 연산은
// 수행하지 않고 true를 리턴하지만 |는 두 연산을 모두 수행해서 그 결과를 리턴
// 한다. 따라서 |보다 ||연산이 보다 더 효율적으로 동작한다.
int charCode = '1';
if((charCode>=65) & (charCode<=90)) {
System.out.println("대문자");
}
if((charCode>=97) & (charCode<=122)) {
System.out.println("소문자");
}
if((charCode>=48) & (charCode<=57)) {
System.out.println("숫자");
}
int value = 6;
if((value%2==0) | (value%3==0)){
System.out.println(value + "은(는) 2 또는 3의 배수입니다");
}
if((value%2==0) || (value%3==0)){
System.out.println(value + "은(는) 2 또는 3의 배수입니다");
}
// String 타입의 문자열을 비교할 때는 대소(>,<,<=,>=)연산자는 사용할 수 없고
// 동등(==,!=)연산자를 사용할 수 있지만 문자열이 같은지 다른지를 비교하는데는
// 사용하지 않는다.
// 그 이유는 String은 기본타입 자료형이 아니라 참조타입자료형이기 ㄸ문이다.
// 따라서, String변수를 비교할 경우에 동등연산자를 사용하면 원하지 않는 결과가
// 나올 수 있다.
String str1 = "소향"; // literal
String str2 = "소향"; // literal
String str3 = new String("소향"); //객체
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println();
// 비교연산자를 사용할 경우
// 참조타입 비교연산시 동등연산자를 사용할 경우 값을 비교하는 것이 아니라
// 참조하는 값(주소)을 비교한다.
System.out.println("str1==str2 =>"+(str1==str2));
System.out.println("str1==str3 =>"+(str1==str3));
System.out.println("str2==str3 =>"+(str2==str3));
// 자바는 문자열리터럴이 동일하다면 동일한 String객체를 참조하도록 되어 있다.
// Java는 리터럴이 동일하다면 Constant Pool에 한개의 값만 생성하도록 되어있다.
// 그래서 str1과 str2는 동일한 String객체의 값(주소)를 가지고 있다
// 그러나 객체생성연산자인 new로 생성한 str3(참조타입, 객체)는 새로운 객체의
// 주소값을 가지고 있기 때문에 동등연산자로 비교할 경우에 동등연산자는 객체의
// 주소를 비교하기 때문에 false라는 결과가 나온다.
// 따라서, 참조타입인 String(객체)의 값만 비교할 경우에는 == 연산자대신에
// equals()메서드를 사용해서 비교해야 한다.
System.out.println("str1.equals(str2) =>" +str1.equals(str2));
System.out.println("str1.equals(str3) =>" +str1.equals(str3));
'일 > JAVA' 카테고리의 다른 글
java05.class.class (0) | 2023.05.24 |
---|---|
java04. ref_type (0) | 2023.05.24 |
java03. if_for (0) | 2023.05.24 |
java01. varibles (0) | 2023.05.23 |
끝없는 자바공부. 객체지향 프로그래밍 (1) | 2023.05.18 |