본문 바로가기
> 개발/JAVA

자바의 기본 자료형 : 숫자자료형, 문자자료형, 형 변환

by @일리 2023. 7. 15.

오늘은 기본자료형 중에서 숫자자료형(정수형, 실수형)과 문자자료형, 그리고 형 변환까지 정리해보겠다.

자료형의 종류

1. 기본자료형 : 정수형, 실수형, 문자형, 논리형

2. 사용자정의 자료형

각 자료형의 크기

  1byte 2byte 4byte 8byte
논리형 boolean      
문자형   char    
정수형 byte short int
(default)
long
실수형     float double
(default)

자료형에 따라서 크기는 1byte부터 8byte까지 다양하다.

1byte = 8bit이고, 1bit는 0과 1을 저장하는 최소의 단위이다. 1bit로 0과 1 두 가지를 표현할 수 있기 때문에 1byte는 2의 8승인 256가지를 표현할 수 있다. 그렇다면 1byte로 표현할 수 있는 숫자는 0부터 255까지일까? 그렇지 않다.

부호 1bit 1bit 1bit 1bit 1bit 1bit 1bit

8bit의 맨 앞에는 MSB(Most Significant Bit)라고 부호(+ 또는 -)를 나타내는 비트가 있다. 숫자에는 음수도 있기 때문에 1byte는 -2의 7승(-128)부터 0, 그리고 2의 7승-1(127)까지 총 256개의 숫자를 나타낼 수 있다. 정수형 default 값인 int는 -2의 31승부터 2의 31승-1까지 -2,147,483,648~2,147,483,647까지 나타낼 수 있다.

 

이와 달리 문자형은 음수와 양수의 값이 구분되지 않기 때문에 char에는 부호 비트가 존재하지 않는다. 그래서 16비트인 2의 16승인 65,536가지(0부터 65,536)를 표현할 수 있다.

진법

진법은 수를 표기하는 기수법(시각적으로 수를 나타내는 방법)이다. 2진수, 8진수, 10진수, 16진수 정도만 알면 된다. 

코드를 작성할 때 숫자가 몇 진수인지 알기 위해서 접두사로 0b, 0, 0x를 붙인다. 이해하기 쉽도록 108을 예로 들어보겠다.

> 2진수(Binary) : 0b1101100

> 8진수(Octal) : 0154

> 10진수 : 108

> 16진수(Hexadecimal) : 0x6c

 

자바에서 숫자를 다른 진법으로 변환하는 법

public class BinaryTest {
    public static void main(String[] args) {
        int decimal = 123;
        String binary = Integer.toBinaryString(decimal);
        String octal = Integer.toOctalString(decimal);
        String hexa = Integer.toHexString(decimal);
        System.out.println("binary = " + binary);
        System.out.println("octal = " + octal);
        System.out.println("hexa = " + hexa);
    }
}

// binary = 1111011
// octal = 173
// hexa = 7b

10진수 숫자를 다른 진법으로 변환하려면 Integer.toBinaryString(number), Integer.toOctalString(number),Integer.toHexString(number) 매소드를 사용하면 된다. 

 

반대로 2진수, 8진수, 16진수 숫자를 10진수로 바꾸려면 parstInt(숫자, 바꿀 진법) 매소드를 사용하면 된다.

import java.sql.SQLOutput;

public class IsNull {
    public static void main(String[] args) {
        String binaryNumber = "1010";
        int decimalNumber = Integer.parseInt(binaryNumber, 2);
        System.out.println("Binary Number: " + binaryNumber);
        System.out.println("Decimal Number: " + decimalNumber);

        // Binary Number: 1010
        // Decimal Number: 10

        String octalNumber = "52"; // Replace this with your octal number
        int decimalNumber2 = Integer.parseInt(octalNumber, 8);
        System.out.println("Octal Number: " + octalNumber);
        System.out.println("Decimal Number: " + decimalNumber2);

        // Octal Number: 52
        // Decimal Number: 42

        String hexadecimalNumber = "1A"; // Replace this with your hexadecimal number
        int decimalNumber3 = Integer.parseInt(hexadecimalNumber, 16);
        System.out.println("Hexadecimal Number: " + hexadecimalNumber);
        System.out.println("Decimal Number: " + decimalNumber3);

        // Hexadecimal Number: 1A
        // Decimal Number: 26

    }
}

2진수, 8진수, 16진수로 나타낸 숫자를 그냥 출력해도 알아서 10진수로 변환해서 숫자를 보여주기도 한다.

public class BinaryTest {
    public static void main(String[] args) {
        int x= 123;
        System.out.println("x = " + x);
        int y = 0b1111011;
        System.out.println("y = " + y);
        int z = 0173;
        System.out.println("z = " + z);
        int u = 0x7B;
        System.out.println("u = " + u);
    }
}

// x = 123
// y = 123
// z = 123
// u = 123

문자자료형 : 아스키코드와 유니코드

1. ASCII 코드

아스키코드는 7비트를 사용하여 128개의 문자를 나타낸다. 아스키코드로는 영어 알파벳(대소문자)과 숫자, 약간의 특수문자만 표현할 수 있다. 아스키코드의 문자는 숫자로도 변환이 가능하다. 예를 들어 'A'는 숫자로 65이다. 그리고 'a'는 숫자 97이다. 대소문자는 32만큼 차이가 나며 대문자가 소문자보다 숫자가 작다. 왠지 반대일 것 같은데 아니여서 신기했다.

 

알파벳 개수가 총 32개여서 대소문자 간의 차이가 32인걸까? 하고 아스키코드표를 찾아봤더니 그렇지 않았다. 알파벳은 총 26개고 Z 이후에 [ ₩ ] ^ _ ` 6개의 특수문자가 a 앞에 있어서 그런거였당ㅋㅋ정리하면 A~Z는 65~90, 그리고 특수문자 91~96까지 6개, a~z는 97~122였다. 

2. 유니코드

유니코드는 ASCII의 한계를 해결하기 위해 등장한 문자 인코딩 표준이다. 유니코드 덕분에 영어가 아닌 언어들도 표현할 수 있는 방법이 생겼다. 자바에서는 문자열을 표현하기 위해 UTF-16을 사용하고 있으며, 영어 외의 언어를 나타내기 위해 한 글자당 2바이트를 사용한다. 만약 자바에서 아스키코드만 지원했다면 char은 2바이트가 아닌 1바이트의 크기를 가졌을 것이다. 알파벳은 1바이트면 충분히 표현할 수 있다.

형 변환(Casting)

기존에 지정해두었던 타입을 다른 타입으로 변경하려면 형변환을 해야 한다. 형 변환에는 자동 형변환과 강제 형변환이 있다. 

 

1. 자동 형변환 = 묵시적 형변환 : 작은 타입이 큰 타입에 저장되는 경우 (예 : byte -> int)

2. 강제 형변환 = 명시적 형변환 : 큰 타입이 작은 타입에 저장되는 경우, 표현할 수 있는 데이터 범위가 달라질 때 등 (예 : int -> byte)

 

        float f1 = 56.7f;
        int f2 = (int)f1;
        System.out.println("f2 = " + f2);
        
        // f2 = 56

(변환할 자료형 타입)을 변수 앞에 써서 강제로 형 변환을 할 수 있다. 강제로 형을 바꿀 경우 잠재적인 정보가 손실 될 수 있으며 예상하지 못한 문제가 발생될 수 있으므로 주의해야 한다.

댓글