본문 바로가기
study_java/java_수강정리(~10.29)

[JAVA]3일차

by developer_j 2020. 5. 13.
728x90
반응형

 

프로그래밍은 성급하게 손가락부터 나가면 에러천국된다. 코드를 어떻게 짤지 생각하는 버릇을 들여야 한다. 생각을 했는데도 잘 진행이 안되면, 그때는 차근차근 하나씩 해보자.

< 수업 3일차 >

 

1byte = 8bit이다. bit는 0과 1로 표현되고, 값은 2진수로 계산된다.

그러므로, 1byte의 공간에 최대로 들어갈 수 있는 숫자는 11111111 ㅡ 2의 8승?

NOPE ! ! ! 아니다.

음의 정수를 표현하기 위해서 컴퓨터는 최상위 비트를 이용한다. 최상위 비트가 0이면 양수, 1이면 음수로 본다. 따라서, 8비트에서 부호 비트인 최상위 비트를 제외하고 계산하면 1byte는 2의 7승까지(-128~+127) 표현이 가능하다는 것을 알 수 있다.

양수라고 가정하고, 01111111 --> 다 더해보면 128이 나온당. (1+2+4+8+16+32+64 = 128 = 1은 2의 6승까지 표현되는데 값을 다 더해보면 2의 7승)

그렇다면 실수형의 소수점도 숫자로 표현할 수 있을까? 소수점의 범위를 생각해본다면, 가능은 하지만 작은 오차가 발생하므로, 출력결과가 정확한 값을 내기 어렵다. 실수형 타입들은 float형은 소수 6자리까지, double형은 소수 15자리까지는 오차없이 표현하지만 그 이상의 소수부분에서는 오차가 발생한다. 그러므로 실수형 변수를 선언할 때는 표현하고자 하는 범위 밖까지 유효 자릿수를 잘 고려해야 한다. 실수형의 오차 문제는 거의 모든 프로그램 개발 과정에서 발생하는 문제이다. 실수형은 대부분 큰 범위의 수에 사용되기 때문에 신중하게 접근하지 않는다면 치명적인 에러가 발생할 수 있다.


 2진법 보수란 무엇인가?

수학에서의 보수란, 특정 수 a가 c라는 결과를 얻기 위해 필요한 b라는 수를 말한다. 즉, a가 c의 결과를 내기 위해 보충하는 수가 b다. 예를 들어 10진수에서 1의 보수는 9다. 한편 2진수의 보수법은 본래 음의 정수를 컴퓨터가 인식할 수 있도록 하기 위해 나온 것으로, 컴퓨터는 정수의 부호를 최상위 비트로 결정한다. 그렇다고 양의 정수 비트의 제일 앞 비트를 1로 바꾼다고 해서 음의 정수 비트 표현이 되는 것이 아니며 이상한 값이 결정된다. 그래서 2진수 보수법이 나오게 되었는데, 원하는 수의 2진수 표현에 보수를 취하고 1을 더하면 해당 양의 정수의 음의정수가 된다.


아스키 코드 유니코드

 CPU는 0과 1로 연산처리를 하므로, 문자도 숫자로 기억한다. 이때, 문자와 숫자를 일대일로 대응시키는데 대부분 아스키 코드 기준에 따른다. 예를들어 ABCD를 .txt로 저장하면 하드디스크에 저장 될 때 2진수 형태로 바뀌어서 저장된다. (HDD도 0101 덩어리만 인식) 이때 저장하려는 문자가 아스키코드에 의해서 바뀐다. 시간이 지나면서 1바이트로 정의된 아스키코드를 확장할 필요성이 증가하였고 (중국어나 영어, 특수기호 등 문자가 너무 많아서) 만들어 진 것이 유니코드인데, 모든 문자를 2바이트(16비트)로 표현하며 자바에서 쓰는건 유니코드이다.


상수 : final과 literal

-  final 상수

public class Lecture03 {
           public static void main(String[] args) {
                       final int MAX_SIZE=100;
                       final char CONST_CHAR='상';        //유니코드에 따라 숫자로 바뀌어서 메모리로 전송된다
                       final int CONST_ASSIGNED;

                       CONST_ASSIGNED = 12;

                       System.out.println("상수 1: " + MAX_SIZE);
                       System.out.println("상수 2: " + CONST_CHAR);
                       System.out.println("상수 3: " + CONST_ASSIGNED);
                       //CONST_ASSIGNED = 20;  --> 한번 할당한 값을 변경 시도했을 때 빨간줄
           }
}

 

public class Lecture032 {
           public static void main(String[] args) {
                       // 원의 넓이 구하기
                       double r = 10;
                       final double PI = 3.14;                 //pi 값은 불변하는 고정된 수치
                       final double WIDE = r * r * PI;        //이것도 원의 넓이를 구하는 고정 공식

                       System.out.println(" 원의 넓이는  "+WIDE+ " 입니다.");
           }
}

그냥 숫자로 돌려도 프로그램은 실행되는데 왜 굳이 final 상수를 선언할까?

상수는 변경할 수 없는 값이다. final 키워드를 붙이면 한번 할당된 값의 final 변수는 이후에 변경이 불가능하다. 그렇기 때문에 다른 동료가 바꾸지 못하도록 하고싶을 때나(절대값) 불변의 공식일 때 선언해준다. final 상수는 알아보기 쉽게 상수명을 대문자로 짓는 것이 관례다.

-  literal 상수

public class Lecture033 {
		public static void main(String[] args) {
				int num = 5 + 7;

				System.out.println(" 원의 넓이는  "+num+ " 입니다.");
           }
}

 리터럴(literals) 역시 상수인데, 어떠한 키워드가 붙은 변수가 아니라 그냥 상수 값으로 선언되는 표현을 말한다.

예를 들어 int num = 5 + 7;의 코드에서, 메모리는 int형 변수 num의 공간을 어떻게 잡을까? num 이름의 메모리칸에 12가 바로 들어갈까? 이에 대한 대답으로 우선, 연산은 CPU에서 진행되는 것을 우리는 알고 있다. CPU에서의 연산이 진행되기 위해서는 처리될 데이터가 반드시 메모리 공간에 Load 되어야한다. 따라서 4바이트짜리 이름없는 메모리 공간에 5와 7이 각각 올라가서 cpu가 연산처리한 후 그 결과를 num 메모리 공간에 다시 넣어 출력한다. 이처럼 코드 상으로 중간에 누군가가 변경이 불가능한 즉각적이고 임시적인 값, 즉 메모리의 이름 없는 공간에 올라가므로 접근과 변경이 불가능한 값을 리터럴이라고 한다.

 

또는, 다음과 같은 코드도 리터럴이다.

public class Lecture034 {
	public static void main(String[] args) {
    		System.out.println(3145167676 + 3261269876); 
    }
}

System.out.println(3145167676 + 3261269876);  --> 이 코드를 컴파일 하게되면 Integer number too large 라는 에러가 뜬다. 이것은 3145167676과 3261269876이 정수형이라서 4 바이트로 메모리 공간을 잡고 계산하고자 했으나, 각 숫자가 4 바이트의 표현 범위를 넘어섰다. 4바이트는 양의 정수 약 21억, 음의 정수 약 -21억까지 표현한다.

따라서, 이처럼 큰 정수를 연산하고 싶다면 다음과 같은 코드로 정수형 크기 최고봉인 long형(8바이트) 상수표현을 요청해주는데, 이외에도 double의 D, float의 f 등의 표현들도 리터럴이다.

☞ System.out.println(3147483647L + 3147483648L);


진수법 별로 표현하기

int num2 = 0b111; // 2진수 표현 : 0b

int num8 = 0123;  // 8진수 표현 : 0(영어 O아님 숫자 0)

int num10 = 123;   // 10진수 표현

int num16 = 0x123; // 16진수 표현 : 0x

 

혹은 숫자를 가시적으로 표현하기

int num = 12_34_56_78_90;  // 출력하면 그냥 1234567890이 나옴.

 


이스케이프 시퀀스를 배우는데, 이클립스에서 버그가 발생한다는 것을 발견했다.

public class Lecture03 {
           public static void main(String[] args) {
                       System.out.println("AB"+"\b"+'C');
                       System.out.println("AB"+'\r'+'C');
           }
}
/* 결과가 이상하게 나옴
    AB?C    --> 원래 결과 : AC
    AB      --> 원래 결과 : CB
    C
*/

 AB?C--> '\b' 백스페이스 버그. 원래 결과 : AC

\b 버그는 구글링 결과 다른 사람들도 겪은 것을 보았지만 \r 버그는 찾지 못했다.  개행문자처럼 출력된다.

하지만 둘다 커맨드 창에서 출력했을 때는 잘나온다.

728x90
반응형

'study_java > java_수강정리(~10.29)' 카테고리의 다른 글

[JAVA]7일차  (0) 2020.05.19
[JAVA]6일차  (0) 2020.05.19
[JAVA]5일차  (0) 2020.05.15
[JAVA]4일차  (0) 2020.05.15
[JAVA]1일차 + 2일차  (0) 2020.05.12