1.4.2 산술 연산
간단한 앱을 만들면서 자바의 기본적인 산술 연산에 관해 알아보자.
자바에서는 소수점을 포함하지 않는 수는 int로, 소수점을 포함하는 수는 double로 다룬다.
주요 산술 연산자
연산자 |
개요 |
+ |
더하기 |
- |
빼기 |
* |
곱하기 |
/ |
나누기 |
% |
나머지 |
자바에서는 이런 산술 연산자를 사용해 수치를 계산한다.
산술 연산은 일반적인 수치 계산 우선순위와 마찬가지로 다음 순서로 계산한다.
. ()로 에워싼 식
. *(곱하기), /(나누기), %(나머지)
. +(더하기), -(빼기)
특수한 산술 연산자
자바에서는 일반적인 산술 연산자 외에도 프로그래밍 언어 특유의 산술 연산자 기술 방법이 있다. 중요한 것을 소개한다.
[구문] 특수한 산술 연산자
변수 += 변수(혹은 값); // + 외에 -, *, /, %도 이용가능
++변수; // ++ 외에 --도 이용가능
변수++; // ++외에 --도 이용가능
예를 들어 result += 2는 result = result + 2와 같다. 다시 말해 연산하기 전에 변수 result의 값이 1이라면 연산 후에는 3이 된다. 이런 기술 방법은 +뿐만 아니라 다른 산술 연산자인 -, *, /,%에서도 이용할 수 있다.
+=는 변수에 1을 더하는 것을 뜻한다.
단, ++를 변수 앞에 쓰는지 뒤에 쓰는지에 따라 계산 시점이 달라지낟.
예를 들어 ++result처럼 ++를 변수 앞에 쓴 것을 인수로 메서드에 전달하면 result는 1이 더해진 상태로 전달된다. 반대로 result++라고 뒤에 쓰면 result에 1이 더해지기 전에ㅢ 상태로 전달된다. 그리고 인수로 넘겨진 후에 1이 더해진다. 마찬가지로 1씩 감소하는 -- 연산자도 있다.
다음 예제를 실행해 산술 연산자의 동작을 확인해보자.
ArithmeticOperator1.java
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package jp.co.bbreak.sokusen. _1._4; /* 산술 연산자를 확인하는 클래스입니다. */ public class artithmeticOperator1 { public static void main(String[] args) { // [1] 특수한 계산 int result = 1; result += 2; System.out.println("[1] result = 1 -> result +=2 -> result =" + result); // [2] 특수한 계산 System.out.println("[2] result = 1 -> ++ result"); result = 1; printValue(++result); System.out.println("result =" + result); // [3] 특수한 계산 System.out.println("[3] result = 1 -> result++"); result = 1; printValue(result++); System.out.println("result =" + result); } /** 전달된 값 value를 화면에 출력한다. @param value 값 */ private static void printValue(int value){ System.out.println("전달된 값: value=" + value); } } |
여기서는 ++ 연산자의 실행 시점을 확인하기 위해 printValue 메서드에 ++ 연산자가 붙은 인수를 전달하고 있다. 그리고 전달된 값을 printValue 메서드에서 화면에 출력한다. 예제코드를 실행하면 다음 결과가 출력된다.
[2]의 ++ result에는 연산자로 계산한 값이 전달되고, [3]의 result++엔ㄴ 연산자로 계산하기 전의 값이 전달됨을 알 수 있다.
문자열에서 + 연산자
+ 연산자는 수치를 더할 때 뿐만 아니라, 문자열을 연결할 때도 이용할 수 있다.
지금까지의 예제에서도 몇 번 이용했었다.
주의할 점은 문자열 뒤에 + 연산자를 붙이면 그 이후에 수치가 와도 모두 문자열로 취급한다는 것이다. 예를 들어보자.
문자열을 + 연산자로 결합한다.
----------------------------------------------------------------------------------------------------------------------------"1 + 1 = " + 1 + 1
// 아래처럼 인식된다.
// "1 + 1 = " + "1" + "1"
----------------------------------------------------------------------------------------------------------------------------
실행 결과는 '1 + 1 = 11' 이라는 문자열이다. 만약 수치를 계산하면서 문자열과 연결해야 할 때는 다음처럼 수치 부분을 괄호로 에워싸야 한다. 그러면 수치로 계산할 수 있다.
()를 사용하면 계산식이 된다.
----------------------------------------------------------------------------------------------------------------------------
"1 + 1 =" + (1 + 1)
----------------------------------------------------------------------------------------------------------------------------
이 경우 실행 결과는 '1 + 1 = 2' 이다.
또한 문자를 연결하는 + 연산자는 왼쪽부터 계산하므로 문자열 앞에 수치가 있으면 수치 게산으로 다룬다. 예를 들어보자.
왼쪽부터 계산한다.
----------------------------------------------------------------------------------------------------------------------------
1 + 2 + "3"
----------------------------------------------------------------------------------------------------------------------------
결과는 '123'이 아니라 문자열 앞에서 수치 '1 + 2'를 계산해 결국 '33'이 출력된다.
단, 이런 식으로 기술하면 어떤 변경이 있어서 수치 앞에 문자열이 오게 되면 원하는 결과를 얻을 수 없게 된다. 문자열 내에서 수치 계산은 ()로 에워싸자.
그럼 지금까지 학습한 연산을 에제로 확인해본다.
부동소수점수를 다루는 산술 연산의 주의점
지금까지 살펴본 것처럼 산술 연산자를 이용해 수치를 계산할 수 있다. 하지만 double이나 float 등 부동소수점수를 계산할 때는 주의해야 한다. 부동소수점수를 계산할 때 오차가 발생해 의도한 값이 되지 않는 경우가 있기 때문에 우선 다음 예제를 실행해 어떤 결과가 나오는지 확인해본다.
이 코드를 실행하면 다음과 같은 결과가 표시된다.
이런 결과는 자바뿐만 아니라 프로그래밍 언어 대부분에서 나타나는 문제로, 소스 코드상에 기술된 10진수를 자바 실행 환경에서 2진수로 변환해 계산하기 때문이다. 부동소수점수에서는 10진수와 2진수 변환 시 오차가 발생하낟.
따라서, 금액 계산 등 오차를 허용하지 않고 정확한 수치를 요구하는 경우에는 다음에 설명할 BigDecimal 클래스를 이용해 계산한다.
BigDecimal 클래스를 이용한 계산
BigDecimal 클래스로 계산 할 때는 우선 BigDecimal의 생성자에 연산 대상 수치를 문자열(""로 에워싼 것)로 전달한다. 연산 대상 수치를 가진 BigDecimal 인스턴스가 생성되면 메서드를 호출해 연산을 실행한다.
BigDecimal의 메서드는 반환값도 BigDecimal 인스턴스이다. BigDecimal 클래스에는 산술 연산자에 대응하는 다음과 같은 메서드가 준비되어 있다.
여기서 주의할 점은 BigDecimal로 나눗셈할 때 나누어떨어지지 않는 수치를 계산하면 java.lang.ArithmeticException 예외가 발생한다는 것이다. 그러므로 나눗셈할 때는 기본적으로 다음과 같은 설정을 한다.
. 계산할 소수점의 자릿수
. 끝 수를 버릴 것인가 올릴 것인가
끝수 처리(맺음 처리0는 java.math.RoundingMode에 정의되어 있다. 다음 표에 자주 사용되는 RoundingMode 상수를 나타냈다.
또한 양 또는 음의 무한대 값에 근접하도록 올림을 할 때는 아래 표의 RoundingMode 상수를 이용하기도 한다.
그럼 BigDecimal을 어떻게 사용할 까?
BigDecimalSample1.java
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package 폴더명 import java.math.BigDecimal; import java.math.RoundingMode; /** * BigDecimal 예즈를 실행하고 내용을 확인하는 클래스이다. */ public class BigDecimalSmmple1 { /** * BigDecimal에서 계산을 실행하고 내용을 확인한다. * @param args * 명령줄 인수. 이번에는 사용하지 않는다. */ public static void main(String[] args) { // [1] 더하기 BigDecimal value1 = new bigDecimal("0.7"); BigDecimal value2 = new BigDecimal("0.1"); BigDecimal result = value1.add(value2); System.out.println("[1]0.7 + 0.1 = " + result); // [2] 빼기 result = value1.subtract(value2); System.out.println("[2] 0.7 - 0.1 = " + result); // [3] 곱하기 result = value1.multiply(value2); System.out.println("[3] 0.7 * 0.1 = " + result); // [4] 나누기 value1 = new BigDecimal("7.0"); value2 = new BigDecimal("3.0"); result = value1.divide(value2, 0, RoundingMode.DOWN); // 소수점 미만을 내림 System.out.println("[4] 7.0 / 3.0 = " + result); // [5] 나머지 value1 = new BigDecimal("7.0"); value2 = new BigDecimal("3.0"); result = value1.remainder(value2); System.out.println("[5] 7.0 % 3.0 = " + result); } } |
결과를 보면 알 수 있듯이 BigDecimal로 계산하면 산술 연산자 사용시 발생하는 오차가 사라져 원하는 값을 얻을 수 있다. 이처럼 오차가 허용되지 않는 부동소수점 계산에서는 BigDecimal을 사용하는 것이 기본이다.
'프로그래밍 > JAVA' 카테고리의 다른 글
1.5.2 참조형 (0) | 2019.02.07 |
---|---|
1.5 자료형 (0) | 2019.01.30 |
1.4 기본적인 계산 (0) | 2019.01.23 |
1.3.7 static 변수와 static 메서드 (0) | 2019.01.23 |
1.3.6 주석 (0) | 2019.01.22 |