[Java] 연산자_2

삶걀·2022년 4월 27일
0

Java

목록 보기
5/15

11. Math.round()로 반올림하기

Math.round()
: 실수를 소수점 첫째자리에서 반올림한 정수를 반환한다.

long result = Math.round(4.52); //result에 5를 저장한다.

Math.round는 첫째자리에서만 반올림을 한다. 그럼 넷째자리나 다른번째에서 반올림을 하고싶으면?

public class Ex_3_1_1 {
	public static void main(String[] args) {
		double pi = 3.141592;
	
		System.out.println(Math.round(pi * 1000) / 1000.0);	
	}
}
출력값: 3.142

출력 과정
Math.round(pi 1000 ) / 1000.0
Math.round(3.141592
1000 ) / 1000.0
Math.round(3141.592 ) / 1000.0
3142 / 1000.0
3.142

여기서 알 수 있는것은 뒤에 나누는 수를 반드시 실수를 써야한다는것이다.
Math.round()값이 정수로 출력되므로 뒤에 나눠주는 수를 실수로 써야 우리가 원하는 소수점 n째 자리에서 반올림한 실수값을 얻을 수 있다.

만약 1000.0이 아니라 1000으로 나눈다면

public class Ex_3_1_1 {
	public static void main(String[] args) {
		double pi = 3.141592;
		
		System.out.println(Math.round(pi * 1000) / 1000);
	}
}
출력값: 3

왜 이런 결과가 나올까? Math.round의 값과 1000 모두 int(정수)로 취급되기 때문에 정수/정수=정수 이므로 출력값도 정수로 나오기 때문이다.

그러면 그냥 반올림 하지 않고 소숫점 뒤를 다 버리고싶으면?

public class Ex_3_1_1 {
	public static void main(String[] args) {
		double pi = 3.141592;
		
		System.out.println((int) (pi * 1000) / 1000.0);	
	}
}
출력값: 3.141

원리
(int)(3.141592 * 1000) / 1000.0
(int)(3141.592) / 1000. 0
3141 / 1000. 0
3.141

->형변환 연산자를 사용하자!


12. 나머지 연산자 (%)

오른쪽 피연산자로 나누고 남은 나머지를 변환
나누는 피연산자는 0이 아닌 실수, 정수만 허용(부호는 무시됨)

public class Ex_3_1_1 {
	public static void main(String[] args) {
		int a = 10;
		int b = 8;
		
		System.out.print(a % b);
	}
}
출력값: 2

10을 8로 나누면 몫은 1이고 나머지가 2이다.
%는 나머지 연산자이므로 출력값은 2가 된다.

나머지연산자는 주로 짝수, 홀수 또는 배수 검사등에 사용된다.
나누는 수는 음수도 허용하지만 부호는 무시된다.(부호 붙이는거 무의미)


13. 비교 연산자

반환값은 반드시 true 또는 false 이다.
비교연산자의 부호는 반드시 =앞에 작성하고, 사이에 공백이 들어가선 안된다.(>=, <=, !=)
!= -> 두 값이 다르면 true, 아니면 fals를 출력
== -> 두 값이 같으면 true, 아니면 fals를 출력

예제
'A' > 'B' -> 65 > 66
(char char -> int int)
출력값: false


14. 문자열의 비교

문자열의 비교에는 == 대신 equals()라는 메소드를 사용해야 한다.
(==도 사용 가능하긴 한데 정확한 값을 얻기 힘듬)

예제 1

public class Ex_3_1_1 {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		System.out.println(str1==str2);
		System.out.println(str1.equals(str2));
	}
}
출력값:true
true

예제 2

public class Ex_3_1_1 {
	public static void main(String[] args) {
		String str1 = new String("abc");
		String str2 = new String("abc");
		System.out.println(str1==str2);
		System.out.println(str1.equals(str2));
	}
}
출력값: false
true

문자열을 만들땐 대부분 예제 1처럼 사용한다.
그러나 예제 2처럼 new Strig을 사용해야하는 경우도 있다.
둘이 같은 값이지만 왜 출력값에서 오류가 발생할까?
왜 이런 결과가 나오는지는 6장, 9장에서 다룬다,

어쨌든 문자열 비교에는 == 대신 equals()를 사용하도록 하자.


15. 논리 연산자 && ||

조건식을 연결할 때 사용하는 연산자로, 두개 이상의 조건이 결합된 경우 사용한다.
||(or), &&(and)를 이용하여 연결한다.

가독성을 위해
10< x && x < 20 이렇게 표시 하기도 한다. (논리연산자 생략은 허용되지 않는다.)

예제1) i는 2의 배수 또는 3의 배수이다
-> 2로 나눴을때 나머지가 0, 3으로 나눴을때 나머지가 0이라는 뜻이므로
i%2==0 || i%3==0
예제2) i는 2의 배수 또는 3의 배수지만 6의 배수는 아니다.
-> 예제1에 and로 조건을 추가하면 된다. (그리고 6의 배수는 아니다)
(i%2==0 || i%3==0) && i%6!=0

연산의 우선순위는 &&가 ||보다 높기때문에 예제2에서 반드시 괄호를 사용해야한다.
||와 &&가 여러개 쓰일 경우 괄호를 사용하는것이 좋다.

예제3) 문자ch는 숫자이다.
사용자가 입력한 문자가 숫자('0'~'9')인지 확인하는 식을 표현하면
'0' <= ch && ch <= '9'
이 식이 가능한 이유는 유니코드에서 문자'0'부터 '9'까지 연속적으로 배치되어 있기 때문에 가능하다.
예제4) 문자ch는 대문자 또는 소문자이다.
사용자가 입력한 문자가 대문자 또는 소문자인지 확인하는 식을 표현하면
('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
대문자, 소문자도 마찬가지로 유니코드에서 연속적으로 값이 배치되어 있기 때문에 가능하다.


16. 논리 부정 연산자 !

등가 비교 현산자 !=와 다른것임
이 연산자는 피연산자가 true면 false, false면 true를 결과로 반환한다.
즉, true와 false를 반대로 바꾸는 역할을 함.

어떤값에 논리 부정 연산자 !를 반복적으로 적용하면 참과 거짓이 반복되며 TV 전원버튼과 같은 '토글 버튼(toggle butten)'을 논리적으로 구현할 수 있다.

'!'가 주로 사용되는 곳은 조건문과 반복문의 조건식이다.
이 연산자를 잘 사용하면 조건식이 보다 이해하기 쉬워짐

예시1) '문자 ch는 소문자가 아니다'를 표현할 때
ch < 'a' || ch > 'z' <---> !('a' <= ch && ch <= 'z')
!를 사용하면 더 이해하기 쉬운 식을 만들 수 있다.

단항 연산자는 결합 방향이 오른쪽>왼쪽이다.

boolean b = true;
!!b -> !!true -> !false -> true
public class Ex_3_1_1 {
	public static void main(String[] args) {
		char ch = 'C';
		
		System.out.printf("%b%n", ch < 'a' || ch > 'z');
	}
}
출력값: true

17. 조건 연산자

조건 연산자는 조건식, 식1, 식2 총 3개의 피연산자를 필요로 하는 삼항 연산자이다.
(삼항 연산자는 조건 연산자 1개 뿐이다.)

조건식 ? 식1 : 식2
첫번째 피연산자 조건식의 평가 결과에 따라 다른 결과를 반환한다.
->조건식이 참(true)이면 식1이, 거짓(false)이면 식2가 연산결과가 된다.
->가독성을 높이기 위해 괄호()로 묶는 경우가 많지만 필수는 아니다.

예제1)
result = (x > y) ? x : y ;
->예제 1에서 만약 x > y이 참이면 변수 result에는 x값이 저장되고, 거짓이면 y값이 저장된다.
만약 x값이 5, y값이 3이라면
result = (5 > 3) ? 5 : 3 ;
result = (true) ? 5 : 3 ;
result = 5;

조건 연산자 -> 조건문인 if문으로 바꿔 쓸 수 있으며 if문 -> 조건 연산자를 바꿔 사용하면 코드를 간단히 할 수 있다.

f (x > y) <---> restlt = (x > y) ? x : y ;
result = x;
else
result = y;

그리고 조건 연산자의 식1, 식2의 피연산자 타입이 다른 경우 이항 연산자처럼 산술변환이 발생한다. (큰 범위로 자동 형변환)

x = x + (mod < 0.5 ? 0 : 0.5 ) //0과 0.5의 타입이 다름
x = x + (mod < 0.5 ? 0.0 : 0.5 ) //0이 0.0으로 자동 형변환됨.

18. 대입 연산자

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

이 연산자는 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다.
그리고 저장된 값을 연산결과로 반환한다.

예제
System.out.println(x = 3); //변수에 3이 저장되고
-> System.out.println(3); //연산결과 3이 출력됨

대입연산자는 연산자들중 가장 낮은 우선순위를 갖고있기 때문에 가장 나중에 수행됨.

또한 연산 진행 방향이 "왼쪽 <----- 오른쪽"이기 때문에
x = y = 3에서
y = 3
x = y
x = 3 이 된다.

lvalue와 rvalue

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

x = 3 (x:lvalue, 3: rvalue)

rvalue는 변수뿐만아니라 식, 상수등 모두 가능하다
반면 lvalue는 반드시 변수처럼 값을 변경할 수 있는 것이여야 한다.
(리터럴, 상수같이 값을 저장할 수 없는 것들은 lvalue가 될 수 없음)

int i = 0;
3 = i + 3; // error. lvalue가 값을 저장할 수 있는 공간이 아님.
i + 3 = i; // error. lvalue의 연산 결과가 리터럴(i+3->0+3->3)

final int MAX = 3; // 변수 앞에 키워드 final을 붙이면 상수가 됨.
MAX = 10; // error. 상수(MAX)에 새로운 값을 저장할 수 없다.

->상수는 값을 저장할 수 있는 공간임. 그러나 한번 값을 저장하면 다른 값으로 변경 불가능.


19. 복합 대입 연산자

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

i=i+3 -> i+=3 로 표현 가능하다. 결합된 두 연산자는 반드시 공백 없이 붙여써야한다.

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 *= 10 + j;i = i * (10 + j);
profile
반숙란 좋아하는사람

0개의 댓글