Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

이번 장에서는 앞장에 이어서 수치표현과 integer 연산자, floating point 연산자들의 쓰임에 대해서 알아보도록 하겠다. 다음과 같은 내용을 다룰 것이다.
  1. 표현에 대한 복습
  2. 수치 연산자들
  3. Integer 연산자
  4. Floating point 연산자
  5. Floating point와 Interger 가 함께 사용될 경우의 표현
  6. 상수 (Constants)
문제 아래의 표현은 정확한가 ? 13 * 6 -

표현 - Expressions

expression은 literals, 연산자, 변수명, 값을 계산하기 위해서 사용되는 괄호등의 조합으로 이루어진다.

표현을 위한 이들 각각의 요소는 올바르게 배열되어야 한다. 보통은 수학에서 보여주는 원칙들이 그대로 사용되기 때문에 직관적으로 사용하는 정도로도 큰 문제없이 문법에 맞는 표현을 사용할 수 있다. 다른 언어들과 마찬가지로 많은 경험을 해보는게 좋은 표현을 만드는 가장 좋은 방법이다.

표현은 operatorsoperands를 가진다. 당신은 연산자가 +,-,*,/ 등이라는 것을 이미 알고 있을 것이다. operand는 연산자에 의해서 계산이 되어지는 값이다.

자바 표현에서 연산자와 operands는 명백하게 구분이 된다. 13 -5 라는 표현에서 13과 5는 operand 이고 -는 연산자다. 14 * sum 에서는 14와 sum이 operands가 된다. 별표는 곱셈연산을 위해서 반드시 사용되어야 한다. 14sum 은 잘못된 표현이다.

다음의 표현에 문제가 있는지 확인하고, 문제가 있다면 교정해보기 바란다.
  • 25
  • 2(a - b)
  • a - b/c +D
  • ( (x+y) / z) / (a -b )
  • 25 - value
  • (a-b) * (c-d)
  • -sum + partial
  • ( (m-n) + (w-x-z) / (p %q)
문제 산술표현에서는 숫자만이 사용될 수 있는가 ?

산술 연산자

산술연산자는 특히 중요하며, 자바는 다음과 같은 산술계산을 위한 연산자를 제공한다. 아래의 산술연산자는 다른 대부분의 언어들이 공통적으로 지원하고 있다.
연산자 의미 우선순위
- 마이너스표시 높음
+ 양수 표시 높음
* 곱하기 중간
/ 나누기 중간
% 나머지 중간
+ 더하기 낮음
- 빼기 낮음
이러한 모든 연산자는 floating point 숫자나 integer 숫자들이 사용된다. 예를들어 / 연산자의 경우는 양쪽에 있는 integer 숫자 혹은 floating point 숫자들을 서로 나누기 위해서 사용한다.

integer 연산은 32bit 혹은 64bit (long형) 크기를 가지는 operand를 사용하게 된다. operand에 사용된 값이 32bit 보다 더 작은 자료형의 값이라고 하더라도 32bit 연산을 하게 된다.

예를 들어 16bit short 변수를 사용한다고 하더라도, 32bit 연산이 수행된다.
   short x = 12;     // 16bit short
   int result;          // 32bit int

   result = x / 3     // 모두 32bit 로 간주되어서 연산이 된다.
x/3은 16bit x 데이터를 32비트 3으로 나누겠다는 표현이라고 생각할 수 있겠지만 실제로는 32bit 데이터 x 를 32비트 3으로 계산을 하고, 그 결과를 32bit 변수인 result에 저장하게 된다.

문제 short 형인 12가 32bit 로 바뀌면 어떤 문제가 발생하는가 ?

다른 예제

여기에 다른 예제가 있다.
short x = 12;
short y = 3;
short value;

value = x/y;
비록 xy가 16비트 크기를 가지고 있다고 하더라도, x/y는 32bit 값 나누기 32bit가 되며, 결과역시 32bit가 된다. 이러한 특성은 전문적인 프로그램영역에서 매우 중요하게 다루어지기도 한다. 그래서 일반적으로 int, long, double 등의 데이터형을 사용하는걸 선호한다. 혹은 type cast (형변환)을 이용하기도 한다. - 형변환에 대한 내용은 한참 뒤에서 다루도록 하겠다. -

문제 아래의 코드를 자바에서 실행했을 때 결과가 현대적인 전자계산기와 같을 것이라고 생각할 수 있는가 ?

Weird Integer Arithmetic

나누기 연산자인 /는 상황에 따라 다른 연산을 한다. 만약 양쪽의 수가 모두 integer이라면 정수형 나누기연산을 한다. 반면 한쪽이라도 floating point number가 된다면 floating point 나누기연산을 하게 된다. 만약 정수형 나누기가 이루어졌다면, 결과도 정수형이 된다. 이는 소숫점 이하의 수는 계산이 되지 않음을 의미한다.

아래의 계산을 Java와 전자 계산기에서 수행할 경우 서로 다른 결과를 보여줄 것이다.
  7/4
전자 계산기는 1.75를 보여주지만, Java는 1을 보여줄 것이다.
7/4 = 1
74 모두 정수형으로 정수형 나누기가 이루어지기 때문으로, 소숫점 이하의 수는 버리게 된다.

문제 다음 표현의 결과값은 ? 199/50

Integer과 Float를 썩으면

정수형 나누기의 계산방식을 이해하는건 별 문제 없을 것이다. 그러나 아래와 같이 짬뽕될 경우 약간 혼란스러울 수 있을 것이다.
1.5 + 7/2
연산자 우선순위에 따라서 + 보다 /연산이 우선 이루어질 것이다. 나누기의 결과는 inger 값인 3이된다. 1.5에 3을 더하니 최종 결과는 4.5 가 된다.

해당 부분에서 발생한 정수형 연산은 다른 부분에 영향을 미치지 않는다. 위의 경우에는 최종적으로 float point + Integer이 되어서 floating point 연산을 수행하게 된다.

문제 다음 표현의 결과는 ? 1/2 + 1/2

Copy-and-Paste 프로그램

정말 제대로된 계산값을 원한다면 위의 수식을 1.0/2.0 + 1.0/2.0으로 바꾸어야 한다. 다음의 자바 프로그램을 컴파일해서 실행시켜 보기 바란다.
class IntegerDivision
{
  public static void main ( String[] args )
  {
    System.out.println("The result is: " + (1/2 + 1/2) );
  }
}

문제 99/100의 결과 값은?

연습

다음은 나눗셈연산을 사용할때 주어지는 sign에 의한 일반적인 결과룰을 보여주고 있다.
+num/+div == +result,  -num/+div == -result,  +num/-div == -result,  -num/-div == +result 
다음은 실예로 위의 룰을 이해하고 있다면 어렵지 않게 결과를 유추해낼 수 있을 것이다.
17/5 == 3,  -17/5 == -3,  17/-5 == -3,  -17/-5 == 3

문제 3/4의 결과는 ?

subexpressions

3/4는 양쪽의 operand가 모두 integer이기 때문에, 정수형 나누기 연산이 수행된다. 소숫점 이하의 계산결과를 보기를 원한다면 3.0/4.0으로 표현을 해야 한다. 거의 대부분의 연산자는 두개의 operand를 가진다. 34+12, 19/3, 90-sum, val * x

그렇지만 단지 하나의 operand를 가지는 연산자들도 있다. +93, -72, +sum, -Math.Pl

subexpression은 표현을 정확하게 하기 위해서 사용하는 expression의 부분이다. (x-y)/2.3, (sum-2) * (sum+3)

문제 34.12 / 68.0이라는 표현에서 /는 정수형 나누기를 하는가 floating point 나누기를 하는가.

Floating point와 Integer 표현을 함께 사용

그럼 연산에서 Integer 과 floating를 함께 사용하면 어떻게 될까 ?
  • operand가 모두 interge : 정수형 연산
  • 하나라도 floating point 라면 : floating point 연산
아래의 예는 float와 integer을 모두 포함하는 예다. (12.0 * 31)/12, (a-2.0)/b, 56*x/3

앞의 두개의 예가 floating point 연산이 될거라는걸 쉽게 이해할 수 있을 것이다. 문제는 56*x인데, x가 float인지 아닌지에 따라서 연산의 종류가 달라진다.

문제 (12 + 0.0) / 7 에서 /의 타입은 ?

더 복잡한 Mixed Expression

이상 연산자에 사용되는 operand 중 하나라도 floating point가 포함되어 있다면, floating point 연산이 수행됨을 알 수 있다. 이러한 규칙이 어떻게 적용될 수 있는지, 아래의 예를 분석해 가면서 알아보도록 하자.

( 1/2 + 3.5 ) / 2.0

괄호안에 있는게 가장 먼저 해석이 되는것을 우리는 알고 있다.
( 1/2 + 3.5 ) / 2.0
  ---
  do first
괄호안의 연산의 경우 /이 '+보다 연산자 우선순위에서 위에 있으므로 1/2 가 먼저 계산될 것이다. 1/2 는 양쪽의 operand가 모두 integer이므로 정수형연산이 이루어질 것이다.
( 0 + 3.5 ) / 2.0

이제 0+3.5 연산이 이루어질 것이다. 한쪽 operand가 floating point형이므로 floating point 연산이 이루어진다.
3.5 / 2.0
양쪽 operand 모두 floating point 형이므로 floating point 연산이 이루어진다. 그러므로 다음과 같은 계산결과를 출력하게 된다.
1.75

문제 (a/b + 4) / 2 표현의 결과를 계산하라. 단 a는 6, b는 12.0 이다.

나누기 연산자

13 을 5로 나눈다면, 다음과 같은 방법에 의해서 계산을 할 것이다.
      2
   --------
 5 | 13
    -----
     10
    -----
      3
13 / 5 == 2이고 나머지는 3을 가진다. 이 식이 맞는지는 13 == 2*5 + 3을 통해서 증명할 수 있다. 종종 나누기의 이 아닌 나머지가 필요한 경우가 있는데, 이때는 %를 사용하면 된다. 이 연산자를 modulo 연산자라고 한다. 다음은 나머지 연산자의 결과와 그 증명이 옳음을 보여주는 간단한 자바프로그램이다.
class RemainderExample
{
  public static void main ( String[] args )
  {
    int quotient, remainder;

    quotient  =  17 / 3;
    remainder =  17 % 3;
    
    System.out.println("The quotient : " + quotient );
    System.out.println("The remainder: " + remainder );
    System.out.println("The original : " + (quotient*3 + remainder) );
  }
}

문제 아래의 표현에서 가장먼저 처리되는 것은 무엇인가. System.out.println("The original : " + (quotient*3 + remainder) );

음수와 양수에서의 나머지 연산

음수에 대한 나머지 연산은 다음과 같은 규칙을 가진다.
  • 오른쪽 operand에 관계없이 : 왼쪽 operand가 음수면 결과도 음수, 양수면 양수
    17 %  3 == 2     -17 %  3 == -2     
    17 % -3 == 2     -17 % -3 == -2

상수

프로그램을 작성하다 보면 종종 상수(constand value)를 사용하는 경우가 있다. 예를 들어 세금계산 프로그램을 짜는데 세율이 0.045% 라면, 이 수는 변하지 않을 것이기 때문이다. 이렇게 값이 변하지 않는다면 상수로 선언할 수 있다. 이렇게 상수로 선언되면 프로그램내에서 결코 바뀔 수 없게 된다.
class CalculateTax
{
  public static void main ( String[] arg )
  {
    final double DURABLE = 0.045;
    final double NONDURABLE = 0.038;

    . . . . . .
  }
}
final은 컴파일러에게 값이 변경되지 않음을 알려준다. 단지 변경되지 않음을 제외하고는 다른 변수와 차이점은 없다.
taxamount = gross * DURABLE ;

그러나 다음의 코드는 컴파일시 에러메시지를 출력하고, 컴파일 실패하게 된다.
DURABLE = 0.441; 
DURABLE 는 상수인데, 값을 변경하려고 했기 때문이다.

이렇게 상수를 사용함으로써 얻을 수 있는 잇점은 아래와 같은 것들이 있다.
  1. 상수는 프로그램을 좀더 쉽게 볼수 있도록 도와준다.
  2. 세율이 0.05로 바뀌었다고 가정해보자. 만약 여러분이 상수를 사용하지 않았다면, 코드내에서 사용된 모든 세율관련 변수명을 찾아서 0.05로 바꾸어줘야 할것이다. 상수로 선언해서 사용했다면, 상수의 값만 변경하면 된다.
문제 final을 이용해서 얻을 수 있는 또다른 잇점에 대해서 생각해 보자.