Java 05

정수, 실수, 문자, boolean 자료형: 무엇을 선택할까요?

int, double, char, boolean이 각각 예시는 있지만 실제로 어떤 기준으로 골라야 하는지 모르겠다.

근거 · 교안 p37-p46

정수, 실수, 문자, boolean 자료형: 무엇을 선택할까요? 대표 이미지

1장: 루나: 자료형, 정의가 아니라 ‘선택’의 문제예요, 솔라!

솔라의 손가락이 노트북 트랙패드 위에서 멈칫했다. 화면에는 방금 막 공부하기 시작한 프로그래밍 개념에 대한 설명이 한 줄 적혀 있었다.

자료형은 변수에 저장할 데이터의 종류와 크기를 정한다.

분명히 한국어이고, 단어 하나하나의 뜻도 알았다. int는 정수, double은 실수, char는 문자 하나, boolean은 참/거짓. 예시 코드까지 여러 번 봤다. 하지만 솔라는 이 문장 앞에서 자꾸만 미아가 되는 기분이었다. 마치 목적지의 주소는 아는데, 그 주소로 가기 위해 버스를 타야 할지 지하철을 타야 할지, 어떤 노선을 골라야 할지 전혀 감이 오지 않는 막막함이었다.

“언니.”

거실에서 책을 읽던 루나를 향해 솔라가 나지막이 불렀다. 목소리에는 짜증과 혼란이 뒤섞여 있었다.

“나 이거 도저히 모르겠어.”

루나가 책에서 눈을 떼고 솔라의 노트북 화면을 들여다보았다. 짧은 문장이 전부였다.

“어떤 부분이 막히는데? int가 정수라는 걸 모르겠다는 뜻은 아닐 테고.”

“그건 알지! int age = 20;, double pi = 3.14; 이런 예제는 수십 번 봤어. 그런데 그게 다야. 이 문장은 그냥 ‘자료형이 이런 역할을 한다’는 정의잖아. 내가 실제로 어떤 값을 변수에 담으려고 할 때, 뭘 보고 int를 선택하고, 뭘 보고 double을 선택해야 하는지, 그 기준을 알려주지 않는다고.”

솔라는 답답한 마음에 손가락으로 화면을 툭툭 쳤다.

“결국 그냥 외우는 건가? ‘나이는 int’, ‘원주율은 double’ 이렇게? 그럼 처음 보는 값을 다룰 땐 어떡해? 그때마다 검색해야 해?”

솔라의 말에는 ‘정의를 아는 것’과 ‘실제로 사용하는 것’ 사이의 거리가 고스란히 묻어났다. 루나는 잠시 생각하더니, 솔라의 노트북을 닫는 대신 다른 질문을 던졌다.

“솔라, 저기 부엌 선반에 컵이랑, 저 옆에 있는 커다란 믹싱 볼이 보이지? 지금 당장 물 한 잔 마시고 싶으면 뭘 쓸 거야?”

“당연히 컵이지.”

너무나 뻔한 질문에 솔라는 의아한 표정을 지었다.

“그럼, 베이킹 하려고 밀가루 1kg을 계량해야 한다면?”

“그땐 믹싱 볼을 써야지. 컵으로는 어림도 없고.”

“바로 그거야.”

루나가 조용히 말했다. 솔라는 여전히 영문을 모르겠다는 얼굴이었다.

“방금 네가 한 게 자료형을 ‘선택’하는 과정이랑 똑같아. 너는 ‘컵은 액체를 담는 용기’, ‘볼은 무언가를 섞는 용기’라는 정의만 떠올리지 않았어. 대신 ‘물을 마신다’는 목적, 그리고 ‘밀가루 1kg’이라는 을 먼저 생각했지. 그리고 그에 맞는 도구를 ‘선택’한 거야.”

루나는 솔라의 노트북 화면을 다시 가리켰다.

“코딩도 마찬가지야. 어떤 값을 변수에 담기 전에, 우리는 두 가지를 먼저 생각해야 해. 첫째, 내가 다루려는 값이 어떤 성격을 가졌는가. 둘째, 그 값이 가질 수 있는 표현 범위는 어디까지인가.”

루나는 솔라가 소화할 시간을 주려는 듯 잠시 말을 멈췄다.

“예를 들어, ‘친구의 나이’를 저장한다고 해보자. 이 값의 성격은 어때?”

“음… 17살, 18살처럼 딱 떨어지는 숫자. 소수점은 없으니까… 정수?”

“맞아. 그게 ‘값의 성격’이야. 정수라는 성격. 그럼 ‘원의 넓이를 계산한 결과’는?”

“3.14 같은 원주율이 들어가니까… 소수점이 있겠네. 실수 성격.”

“좋아. 마지막으로 ‘로그인 성공 여부’는 어때? 이건 숫자야?”

“아니. ‘성공’ 또는 ‘실패’, ‘참’ 또는 ‘거짓’ 같은 상태를 나타내는 거니까… 이건 논리적인 성격?”

솔라는 자기도 모르게 루나의 질문에 맞춰 값들을 분류하고 있었다. 컵과 믹싱 볼을 고를 때처럼, 값의 쓰임새와 형태를 먼저 떠올렸다.

루나가 고개를 끄덕였다. “바로 그거야. 정수, 실수, 논리. 그게 바로 ‘값의 성격’에 따라 그릇의 종류를 고르는 첫 번째 기준이야. 그리고 ‘표현 범위’는 그릇의 크기를 정하는 두 번째 기준이지. 친구 나이가 20억 살을 넘을 일은 없겠지만, 만약 전 세계 인구를 다룬다면 아주 큰 숫자를 담을 그릇이 필요할 테니까.”

그제야 솔라의 눈이 반짝였다. 아까는 무의미한 정의처럼 보였던 문장이 전혀 다르게 읽히기 시작했다.

자료형은 변수에 저장할 데이터의 종류와 크기를 정한다.

“아…!”

솔라의 입에서 짧은 탄성이 터져 나왔다.

“그럼 저기서 말하는 ‘종류’가 언니가 말한 ‘값의 성격’이고, ‘크기’가 ‘표현 범위’를 뜻하는 거였구나. 나는 이 문장을 그냥 ‘자료형이란 무엇인가’에 대한 설명문으로만 읽었어. 이게 사실은 자료형을 선택하는 두 가지 핵심 기준을 알려주는 안내문이었는데!”

머릿속에 흩어져 있던 int, double, boolean이라는 이름표들이 제자리를 찾아가는 느낌이었다. 그것들은 그저 외워야 할 단어가 아니라, 내가 다룰 데이터의 ‘성격’과 ‘범위’를 따져보고 신중하게 내려야 할 ‘선택’지들이었다.

한 고비를 넘겼다는 후련함도 잠시, 솔라의 머릿속에 새로운 질문이 떠올랐다.

“알겠어, 언니. 이제부터 어떤 값을 보면 ‘이건 어떤 성격이지? 얼마나 커질 수 있지?‘라고 먼저 질문해야 한다는 건 확실히 알겠어. 그런데… 그 다음이 문제야. ‘정수’라는 성격을 파악했다고 해도, 정수를 담는 자료형이 int 말고도 더 있다며. 그럼 그 기준을 가지고 int랑 다른 정수형은 어떻게 구별해서 선택하는 거야? 기준은 손에 쥐었는데, 막상 선택지들이 놓이니까 또 막막해지네.”

2장: 루나: 정수는 ‘int’가 기본, ‘long’은 언제 필요할까요?

솔라는 결심했다는 듯 노트북을 열었다. ‘값의 성격’과 ‘표현 범위’라는 두 개의 기준을 손에 쥐었으니, 이제 직접 시험해 볼 차례였다. 어제 루나 언니와 나눴던 대화의 핵심은 간단했다. 데이터를 담기 전에 그릇의 종류(성격)와 크기(범위)를 먼저 생각하라는 것.

솔라는 키보드 위에서 손가락을 잠시 멈추고 생각에 잠겼다. 첫 번째 실험 대상은 가장 만만해 보이는 ‘정수’였다. 소수점이 없는 깔끔한 숫자. 솔라는 먼저 자신의 나이를 변수에 담아보기로 했다. 코드 편집기에 익숙하게 타이핑했다.

int myAge = 20;

아무런 문제 없이 한 줄의 코드가 완성되었다. ‘좋아. 나이는 정수니까 int 그릇에 잘 담기네.’

다음은 ‘표현 범위’를 시험해 볼 차례였다. 솔라는 머릿속으로 떠올릴 수 있는 가장 큰 정수 중 하나인 전 세계 인구를 떠올렸다. 대략 80억 명. 이것도 소수점이 없는 분명한 정수였다. 솔라는 자신 있게 다음 줄을 써 내려갔다.

int worldPopulation = 8000000000;

하지만 코드를 완성하기도 전에, 숫자 8000000000 아래에 불길한 빨간 밑줄이 그어졌다. 컴퓨터가 화를 내는 것 같았다.

“어?”

솔라의 입에서 의아한 소리가 터져 나왔다.

“왜 안 되지? 80억도 똑같은 정수인데. 소수점도 없잖아. ‘정수’라는 성격에 맞는 int 그릇을 쓴 건데, 왜 이건 담을 수 없다는 거야?”

솔라는 myAgeworldPopulation 두 줄을 번갈아 쳐다봤다. 똑같은 int를 사용했는데, 20은 되고 80억은 안 되는 상황을 이해할 수 없었다. ‘표현 범위’라는 기준이 여기서 작동하는 것 같긴 한데, 어떻게 적용해야 할지 감이 잡히지 않았다.

그때, 책을 넘기던 루나가 솔라의 혼잣말을 듣고 조용히 다가왔다. 노트북 화면의 빨간 밑줄을 한번 보더니, 어제의 대화를 이어받았다.

“솔라, 물 한 잔은 컵에 잘 담았네. 그런데 지금은 바닷물을 컵에 담으려는 것 같아.”

“바닷물이라니? 둘 다 그냥 ‘정수’잖아. 똑같은 종류의 물인데.”

“맞아, 종류는 같아. ‘정수’라는 성격은 정확히 파악했어. 문제는 그릇의 크기야. int라는 컵은 생각보다 크지 않아.”

루나는 키보드를 몇 번 두드려 인터넷 검색창을 열고 ‘int 최대값’이라고 입력했다. 화면에 익숙하면서도 낯선 숫자가 나타났다. 2,147,483,647.

int라는 컵은 대략 21억 개 정도의 물건만 담을 수 있도록 만들어졌어. 그 이상을 담으려고 하니, 컵이 넘쳐버린다고 컴퓨터가 알려주는 거야. 네가 넣으려는 80억은 21억보다 훨씬 크니까.”

그제야 솔라는 빨간 밑줄의 의미를 어렴풋이 깨달았다. int는 ‘모든’ 정수를 위한 만능 그릇이 아니라, 특정 크기 제한이 있는 ‘기본’ 그릇이었던 것이다.

“그럼 이렇게 큰 숫자는 어디에 담아? 더 큰 그릇이 있는 거야?”

“응. 정수를 담는 그릇 중에는 int라는 일반 컵 말고, 훨씬 더 큰 long이라는 믹싱 볼도 있어.”

루나는 솔라가 쓴 코드의 intlong으로 바꾸도록 했다.

long worldPopulation = 8000000000L;

솔라가 long으로 바꾸자, 신기하게도 빨간 밑줄이 사라졌다. 그런데 숫자 뒤에 붙은 L이 눈에 거슬렸다.

“언니, 이 L은 뭐야? 갑자기 왜 붙었어?”

“좋은 질문이야. 그건 컴퓨터에게 ‘이 숫자는 일부러 크게 썼으니, 처음부터 long이라는 큰 그릇을 준비해줘’라고 알려주는 표식 같은 거야. 이 표식이 없으면 컴퓨터는 일단 int 컵에 담아보려다 ‘어, 넘치네?’ 하고 당황할 수 있거든.”

솔라의 눈이 동그래졌다. intlong의 관계가 명확하게 그려지는 순간이었다.

“아! 이제 알겠다. 정수 값을 다룰 때는 일단 int를 기본으로 생각하면 되는 거구나. 대부분의 숫자, 예를 들면 나이나 날짜, 책 페이지 같은 건 21억을 넘을 일이 거의 없으니까. 그러다가 게임 머니나, 국가 예산, 아니면 방금처럼 인구수 같이 아주 큰 숫자를 다뤄야 할 때만 특별히 long이라는 더 큰 그릇을 꺼내 쓰는 거네!”

솔라는 자신이 얻은 깨달음을 정리하며 중얼거렸다. 이것은 더 이상 암기가 아니었다. ‘일단 기본 그릇을 쓰고, 넘칠 것 같으면 큰 그릇으로 바꾼다’는 실용적인 선택 전략이었다. ‘정수형 선택 전략’이라는 이름표를 붙여도 될 것 같았다.

자신감이 붙은 솔라는 한 걸음 더 나아가 보기로 했다.

“좋아, 정수는 이제 감 잡았어. 그런데 언니, 소수점이 있는 숫자들은 어때? 예를 들어 평균 점수 95.5 같은 거 말이야. 이런 실수를 담는 double이라는 그릇이 있다고 했잖아. 혹시 실수에도 double 말고 더 크거나 작은 그릇이 따로 있어? 이것도 정수처럼 기본 선택지가 있고, 필요할 때 다른 걸 고르는 방식인 거야?“

3장: 루나: 실수, ‘double’이 정석, ‘float’은 특별한 상황에!

정수형 자료형의 선택 기준을 깨우친 솔라는 자신감이 붙었다. 이제 ‘값의 성격’과 ‘표현 범위’라는 두 개의 렌즈로 세상을 보는 법을 알 것 같았다. 솔라는 의기양양하게 노트북 코드 편집기에 새로운 실험장을 마련했다. 이번 탐구 대상은 ‘소수점’이 있는 숫자, 즉 실수였다.

솔라는 먼저 자신의 학기 평균 점수를 변수로 선언해 보았다. 소수점이 있으니 ‘실수’ 성격. 예제에서 봤던 double을 사용하는 것은 자연스러웠다.

double averageScore = 95.5;

코드는 깔끔하게 한 줄로 완성되었다. 하지만 솔라의 실험은 여기서 끝나지 않았다. 그녀는 강의 자료 어딘가에서 double 말고 float이라는 또 다른 실수 자료형의 이름을 본 기억이 났다. intlong이라는 짝이 있었던 것처럼, double에도 비슷한 짝이 있는 게 아닐까? 솔라는 double 선언 바로 아래에 비교를 위한 코드를 한 줄 더 추가했다.

float averageScore_f = 95.5;

그러자 95.5 아래에 int 때와는 다른 종류의 오류 표시가 나타났다. 컴퓨터는 이 숫자를 float에 담으려면 숫자 뒤에 f를 붙여 95.5f로 만들어야 한다고 제안했다.

“어? long 쓸 때 L 붙이는 거랑 비슷하네. 이것도 뭔가 특별한 이유가 있나?”

일단 컴퓨터의 제안대로 f를 붙여 오류를 없앤 솔라는, 다음 단계로 넘어갔다. ‘표현 범위’를 시험해 볼 차례였다. 정수 때와 달리 실수의 ‘범위’는 얼마나 큰 숫자를 담느냐의 문제만은 아닐 것 같았다. 어쩌면 소수점 이하의 ‘정밀함’과 관련이 있을지도 모른다. 솔라는 인터넷에서 원주율(π) 값을 찾아 최대한 길게 복사한 뒤, 두 변수에 각각 붙여넣었다.

double pi_d = 3.141592653589793;
float  pi_f  = 3.141592653589793f;

double 변수는 조용했다. 하지만 float 변수에 값을 넣자마자, 솔라의 눈썹이 꿈틀했다. IDE가 pi_f 변수 아래에 밑줄을 그으며 ‘정밀도 손실 가능성’을 경고하고 있었다.

“정밀도 손실? 이게 무슨 말이지? 숫자가 너무 길어서 잘린다는 건가?”

솔라는 두 변수의 값을 화면에 출력해보기로 했다. 결과는 충격적이었다.

pi_d 출력값: 3.141592653589793
pi_f 출력값: 3.1415927

double은 원래 값을 정확하게 기억하고 있었지만, float은 소수점 일곱 번째 자리에서 제멋대로 값을 반올림해 버렸다. 나머지 뒷자리는 그냥 증발해 버린 것처럼 보였다. 똑같은 ‘실수’ 성격의 값을 넣었는데, 왜 한쪽은 기억하고 다른 쪽은 잊어버리는 걸까? 솔라는 intlong의 관계처럼 단순히 그릇 크기의 문제라고 생각했던 자신의 예상이 빗나갔음을 직감했다.

“단순히 크기 문제가 아닌가 보네. float은 왜 숫자를 제대로 기억하지 못하는 거지?”

솔라의 중얼거림에, 소파에서 무선 이어폰을 정리하던 루나가 다가왔다. 화면에 나란히 찍힌 두 개의 원주율 값을 본 루나는 말없이 책상 위 연필꽂이로 손을 뻗었다. 그리고는 뭉툭한 4B 연필 한 자루와 아주 뾰족하게 깎은 샤프 한 자루를 꺼내 솔라 앞에 놓았다.

“솔라, 작은 메모지에 전화번호를 급하게 받아 적어야 한다면 둘 중 뭘 쓸래?”

“음… 아무거나? 굳이 고르자면 뭉툭한 연필? 쓰기 편하니까.”

“그럼, 1밀리미터 간격으로 눈금이 그려진 모눈종이에 아주 정교한 회로도를 그려야 한다면?”

루나의 두 번째 질문에 솔라는 망설임 없이 샤프를 가리켰다.

“당연히 샤프지. 연필로는 그 작은 칸에 정확하게 선을 그을 수 없잖아.”

바로 그 순간, 솔라는 연필과 샤프, 그리고 화면 속 두 개의 원주율 값 사이에 어떤 연결고리가 있음을 깨달았다. 루나가 조용히 설명을 보탰다.

“실수 자료형의 선택은 ‘얼마나 큰 숫자를 담느냐’의 문제이기도 하지만, 그보다 더 중요한 건 ‘얼마나 정밀하게 표현할 수 있느냐’의 문제야. intlong이 그릇의 전체 부피를 따지는 거였다면, floatdouble은 그 그릇에 눈금을 얼마나 촘촘하게 새길 수 있느냐의 차이지.”

루나는 화면의 float 변수가 출력한 엉뚱한 값을 가리켰다.

float은 뭉툭한 4B 연필 같은 거야. 대강의 모양은 그릴 수 있지만, 세밀한 부분으로 들어가면 선이 뭉개져서 정확한 표현이 불가능해져. 반면 double은 아주 뾰족한 샤프심 같아서, 훨씬 더 촘촘하고 정밀하게 값을 기록할 수 있지.”

솔라의 입에서 작은 탄성이 터져 나왔다.

“아! 그래서 정밀도 손실 경고가 떴던 거구나. float이라는 뭉툭한 연필로는 내가 복사한 긴 소수점 자리들을 다 표현할 수 없어서 중간에 뭉개버린 거였어. 그래서 우리가 보통 실수를 다룰 땐, 정밀한 샤프인 double을 기본으로 쓰는 거구나! 만에 하나 있을지 모를 오차를 줄이기 위해서.”

솔라는 이제 f 접미사의 의미도 새롭게 이해했다. 그것은 단순히 문법 규칙이 아니었다. ‘나는 지금 뭉툭한 연필을 일부러 쓰고 있다는 걸 알고 있어. 정밀도가 좀 손실돼도 괜찮아’라고 컴퓨터에게 보내는 의도적인 신호였다. 메모리를 아주 아껴야 하는 특수한 상황이 아니라면, 굳이 뭉툭한 연필을 고집할 이유가 없었다.

‘실수형 선택 전략’이 머릿속에 정리되었다. 기본은 정밀한 double. float은 특별한 이유가 있을 때만 신중하게 고려한다.

숫자를 다루는 두 개의 큰 산(정수와 실수)을 넘었다는 생각에 뿌듯함이 밀려왔다. 솔라는 만족스럽게 노트북을 정리하려다 문득 키보드의 글자들을 보았다. ‘A’, ‘B’, ‘C’…

“잠깐만. 그럼 숫자가 아닌 값들은 어떡하지? 예를 들어, 내 혈액형 ‘A’형 같은 문자 하나. 이건 정수도 아니고 실수도 아니잖아. 그리고 게임에서 ‘계속하시겠습니까?’라고 물어볼 때 나오는 ‘예/아니오’ 같은 선택지는? 이런 값들은 어떤 종류의 그릇에 담아야 하는 거야?“

4장: 루나: 문자 하나는 ‘char’, 참/거짓은 ‘boolean’으로!

숫자와의 씨름을 끝낸 솔라는 노트북 옆에 놓인 키보드로 시선을 돌렸다. 정수와 실수를 담는 그릇들을 어느 정도 파악했지만, 키보드 위를 빼곡히 채운 ‘A’, ‘B’, ‘C’ 같은 글자들과 ’?’, ’!’ 같은 기호들은 여전히 낯선 영역이었다. ‘이런 값들은 어떤 그릇에 담아야 할까?’ 이전 장에서 떠올렸던 질문이 눈앞의 키보드와 겹쳐지며 다시금 솔라를 자극했다.

솔라는 곧장 코드 편집기를 열었다. 생각만 하는 대신 직접 부딪혀보기로 한 것이다. 첫 번째 실험 대상은 ‘혈액형’이었다. 자신의 혈액형인 ‘A’를 저장해 보기로 했다. 강의 자료에서 봤던 char라는 자료형과, 문자를 감싸던 작은따옴표(' ')를 기억해냈다.

char bloodType = 'A';

코드는 아무런 저항 없이 순순히 받아들여졌다. ‘좋아, 문자 하나는 char에 담는 게 맞구나.’ 안도하는 것도 잠시, 솔라의 머릿속에 장난기가 스쳤다.

“만약 혈액형이 ‘AB’형이라면?”

솔라는 방금 작성한 코드의 'A''AB'로 수정했다.

char bloodType = 'AB';

입력을 마치기가 무섭게, 'AB' 아래로 익숙하지만 반갑지 않은 빨간 밑줄이 그어졌다. IDE는 ‘문자가 너무 많다’는 식의 불평을 쏟아냈다.

“왜 안 되는 거야? 이것도 그냥 문자인데. ‘A’는 되고 ‘AB’는 안 된다니. char가 ‘character’의 줄임말 아니었어? 글자들을 담는 그릇이잖아.”

솔라는 이해할 수 없었다. 똑같은 ‘문자’라는 성격의 값인데, 한 개일 때와 두 개일 때 컴퓨터의 반응이 완전히 달랐다. ‘값의 성격’이라는 기준만으로는 풀리지 않는 문제였다.

그때, 솔라의 혼잣말을 들은 루나가 화면을 들여다보았다. 루나는 정답을 알려주는 대신, 솔라가 이미 알고 있는 것을 가리켰다.

“솔라, 그 char 자료형을 쓸 때, 값을 감싸는 기호가 뭐였지?”

“작은따옴표(' ').”

“맞아. 그 작은따옴표는 그냥 예쁘라고 있는 장식품이 아니야. 컴퓨터에게 보내는 아주 강력한 약속의 증표지.”

루나는 손가락 두 개를 오므려 작은 원을 만들었다가, 다시 엄지와 검지만으로 아주 작은 틈을 만들었다.

“작은따옴표는 컴퓨터에게 ‘이 안에는 딱 한 자리만 들어갈 거야. 딱 하나의 글자만 있을 테니, 그렇게 알고 준비해줘’라고 말하는 것과 같아. 그런데 방금 솔라 너는 그 한 자리 약속에 두 명을 억지로 밀어 넣으려고 한 거야.”

루나의 설명에 솔라의 눈이 동그래졌다. char의 빨간 밑줄이 다른 의미로 보이기 시작했다. 그것은 단순한 오류가 아니라 ‘약속 위반’에 대한 경고였다. char는 ‘문자들(characters)’을 위한 자료형이 아니라, ‘단 하나의 문자(a single character)’를 위한 지독할 정도로 엄격한 원칙주의자였던 것이다.

“아…! char는 개수 제한이 있는 거였구나. 무조건 딱 하나만. 그래서 이름이 chars가 아니라 char인 건가.”

문자 하나에 대한 미스터리를 해결한 솔라는 다음 탐구 주제로 넘어갔다. 게임을 하다 보면 흔히 마주치는 ‘계속하시겠습니까? (예/아니오)’ 같은 선택지였다. ‘성공/실패’, ‘참/거짓’과 같은 논리적인 상태. 이건 boolean이라는 자료형이 어울렸다.

boolean isContinued = true;

코드는 매끄럽게 작성됐다. 솔라는 여기서 한 걸음 더 나아갔다. 어떤 프로그래밍 글에서 참(true)은 1로, 거짓(false)은 0으로 표현하기도 한다는 내용을 본 기억이 났다.

“어차피 참/거짓 두 가지 상태만 있는 거라면, 1이랑 0으로 해도 알아듣지 않을까?”

솔라는 자신의 가설을 증명하기 위해 코드를 수정했다.

boolean isContinued = 1;

하지만 이번에도 컴퓨터는 단호했다. 숫자 1 아래에 빨간 밑줄이 그어지며, boolean 변수에는 숫자(int)를 넣을 수 없다고 항의했다.

“이건 또 왜? 1이 참이라는 건 거의 상식 아니야? 컴퓨터가 너무 깐깐한 거 아니냐고.”

솔라의 볼멘소리에 루나가 조용히 반문했다.

“정말 그럴까? 만약 isContinued = 1;이라는 코드를 다른 개발자가 봤다고 생각해 봐. 그 사람은 이게 ‘참’이라는 뜻인지, 아니면 ‘1단계부터 계속’이라는 뜻인지, 혹은 ‘플레이어 1번이 계속한다’는 뜻인지 어떻게 확신할 수 있을까?”

루나의 질문은 허를 찔렀다. 1과 0은 상황에 따라 너무나 많은 의미를 가질 수 있었다.

boolean 자료형이 truefalse라는 단어만 고집하는 건, 깐깐해서가 아니라 ‘오해의 여지’를 완전히 없애기 위해서야. 누가 봐도 ‘참이다’, ‘거짓이다’라는 명백한 논리 상태 외에는 그 어떤 다른 해석도 허용하지 않겠다는 안전장치인 셈이지.”

그제야 솔라는 무릎을 쳤다. char의 작은따옴표와 booleantrue, false는 단순한 문법 규칙이 아니었다. 그것은 데이터의 ‘성격’을 더욱 명확하고 안전하게 만들기 위한, 프로그래밍 언어 설계자들이 마련해 둔 최소한의 약속이자 울타리였다. char는 ‘오직 하나’라는 제약으로 문자의 단일성을 보장하고, boolean은 ‘true/false’라는 단어로 논리의 명확성을 보장하는 것이었다.

‘비숫자형 선택 전략’이 머릿속에 그려졌다. 한 글자는 char. 참/거짓은 boolean. 간단하지만 누구도 거스를 수 없는 강력한 규칙이었다.

정수, 실수에 이어 문자, 논리값까지. 이제 웬만한 기본 데이터는 자신 있게 그릇에 나눠 담을 수 있을 것 같았다. 뿌듯함을 느끼며 솔라는 지금까지 배운 것들을 머릿속으로 정리했다.

“좋아. 그럼 이제 정리해 보면… 나이나 개수처럼 딱 떨어지는 정수는 int를 기본으로 쓰되, 21억이 넘는 큰 수는 long을 쓰고. 평균 점수처럼 정밀한 소수점 계산이 필요하면 double을 쓰고. ‘A’처럼 문자 하나는 char, ‘로그인 여부’처럼 참/거짓은 boolean….”

자신 있게 각 자료형의 용도를 읊던 솔라의 목소리가 점점 작아졌다.

“그런데… 이걸 실제 상황에서 한꺼번에 쓰려면 어떻게 하지? 예를 들어서 회원 정보를 관리하는 프로그램을 만든다고 치면, ‘나이’, ‘키’, ‘이름 첫 글자 이니셜’, ‘유료 회원 여부’ 같은 정보가 다 필요할 텐데. 이걸 각각 int, double, char, boolean으로 정하는 건 알겠어. 그런데… 이 선택들이 모여서 하나의 프로그램을 이룰 때, 내가 내린 결정이 최선인지 어떻게 확신할 수 있을까? 전체적인 관점에서 이 선택들을 조율하는 더 큰 원칙 같은 건 없을까?”

5장: 루나: 자료형 선택, 데이터의 ‘의도’와 ‘안전’으로 최종 판단해요!

개별 자료형에 대한 탐구를 마친 솔라의 손가락이 키보드 위에서 허공을 맴돌았다. int, double, char, boolean. 각각의 그릇들이 어떤 성격의 값을 담는지, 어떤 제약이 있는지는 이제 알겠다. 하지만 이 지식의 조각들을 실제 프로젝트라는 큰 판 위에서 어떻게 조합해야 할지는 또 다른 문제였다. 막연한 고민 대신, 솔라는 직접 부딪혀보기로 했다.

노트북 화면에 새로운 텍스트 파일을 열고, 이전 장 마지막에 떠올렸던 ‘회원 정보 관리 프로그램’을 위한 데이터 목록을 만들기 시작했다.

[ 회원 정보 ]
- 나이:
- 키:
- 몸무게:
- 이름 첫 이니셜:
- 유료 회원 여부:
- 평균 방문 횟수(월):

솔라는 각 항목 옆에 지금까지 배운 지식을 바탕으로 가장 적절해 보이는 자료형을 적어 내려갔다.

나이: int 이름 첫 이니셜: char 유료 회원 여부: boolean

여기까지는 막힘이 없었다. 딱 떨어지는 정수, 단 하나의 문자, 명확한 참/거짓. 배운 대로 적용하면 되는 간단한 문제였다. 하지만 ‘키’와 ‘몸무게’ 항목에서 솔라의 손가락이 멈췄다.

“키가 170cm면 정수인데, 170.5cm일 수도 있잖아. 그럼 double인가? 몸무게도 65kg일 수도, 65.8kg일 수도 있고… double로 통일하는 게 편한가? 아니, 평균 방문 횟수는 3.5회 같은 건 없으니까 이건 int가 맞겠지?”

개별 항목만 보면 여러 가능성이 떠올랐다. double은 정수까지 담을 수 있으니, 숫자처럼 보이는 건 전부 double로 처리하면 안전하지 않을까 하는 생각마저 들었다. 하지만 그건 어쩐지 모든 음식을 커다란 믹싱 볼에 담아두는 것 같아 찜찜했다. 각 데이터에 딱 맞는 최선의 선택이 있을 것만 같았다. 솔라는 자신이 만든 불완전한 목록을 보며 혼잣말을 했다.

“하나씩 볼 땐 알겠는데, 이렇게 모아놓고 보니 뭘 선택해야 최선인지 확신이 안 서네.”

솔라의 고민을 들은 루나는 소파에서 일어나 다가왔다. 화면의 목록과 솔라의 굳은 표정을 번갈아 보더니, 질문을 하나 던졌다.

“솔라, 네가 만약 이 회원 정보를 관리하는 개발자라면, 어떤 실수가 일어나지 않도록 가장 신경 쓸 것 같아?”

“실수?”

솔라는 예상 밖의 질문에 잠시 생각에 잠겼다.

“음… 일단 나이가 20.5살처럼 소수점으로 입력되거나, -10살처럼 음수가 되면 안 되겠지. 그리고 유료 회원인데 아니라고 하거나, 그 반대의 경우가 생기면 큰일 날 거고.”

“바로 그거야. 자료형을 선택하는 마지막 기준은 바로 ‘의도’와 ‘안전’이야.”

루나는 솔라의 목록을 가리켰다.

“지금 솔라 네가 한 것처럼, 각 데이터의 성격과 표현 범위를 따지는 건 첫 단계야. 훌륭한 시작이지. 하지만 거기서 한 걸음 더 나아가야 해. ‘그래서 이 데이터를 가지고 무엇을 할 것인가(의도)?’ 그리고 ‘어떤 잠재적 오류를 막아야 하는가(안전)?’ 이 두 가지를 스스로에게 물어봐야 해.”

루나의 말에 솔라의 머릿속에서 흩어져 있던 기준들이 하나의 틀로 맞춰지는 느낌이 들었다. ‘값의 성격’, ‘표현 범위’, 그리고 ‘의도와 안전’.

“‘나이’를 다시 봐봐. 왜 double이 아니라 int가 더 좋은 선택일까? double도 20 같은 정수를 담을 수 있는데.”

루나의 질문에 솔라는 방금 자신이 했던 말을 떠올렸다.

“아! 나이는 소수점이 없다는 ‘성격’도 있지만, 만에 하나 20.5 같은 값이 들어오는 걸 막아야 한다는 ‘안전’의 목적도 있는 거구나. int로 선언하면 소수점을 가진 값을 넣으려는 시도 자체가 원천적으로 불가능해지니까. int가 더 안전한 선택이네.”

깨달음은 ‘키’와 ‘몸무게’로 이어졌다.

“그럼 키는? 키도 170.5cm처럼 소수점이 가능하니까 double을 쓸 수 있겠네. 하지만 보통 키는 반올림해서 cm 단위 정수로 관리하는 경우가 많지 않나? 만약 우리 프로그램이 정수만 다루기로 ‘의도’했다면 int가 맞을 수도 있겠다.”

“맞아. 그건 프로그램의 정책, 즉 ‘의도’에 따라 달라져. 만약 정밀한 의료 데이터를 다룬다면 double이 필수적이겠지만, 일반적인 회원 정보라면 int로 충분할 수 있지. 중요한 건 ‘왜 이 자료형을 선택했는가’를 설명할 수 있는 거야.”

그렇다면 몸무게는 어떨까? 65kg와 65.8kg의 차이는 건강 관리 앱이라면 매우 중요한 정보다. 정보가 잘려나가면 안 된다.

“몸무게는 double이 더 안전하겠어. int로 했다가 65.8kg 같은 값을 65kg로 저장해 버리면 정보가 손실되니까. 이건 막아야 할 ‘오류’야.”

솔라는 자신이 망설였던 부분들이 명쾌하게 정리되는 것을 느꼈다. 그것은 단순히 ‘정의’를 암기하는 것과는 차원이 다른, 능동적인 ‘의사결정’ 과정이었다. 솔라는 자신감을 되찾고 다시 키보드에 손을 올렸다. 그리고 아까와는 전혀 다른 기준으로 자신의 목록을 완성해 나갔다. 각 선택지 옆에는 그 이유를 주석처럼 달았다.

[ 회원 정보 ]
- 나이: int             // 소수점, 음수 입력을 막는 '안전한' 선택.
- 키: int               // cm 단위 정수로 관리하기로 '의도'. 소수점 불필요.
- 몸무게: double          // 0.1kg 단위의 정밀도가 중요. 데이터 손실 방지를 위한 '안전한' 선택.
- 이름 첫 이니셜: char    // '한 글자'만 허용하는 제약 자체가 '안전장치'.
- 유료 회원 여부: boolean   // true/false 외 다른 해석을 막아 명확성을 보장하는 '안전장치'.
- 평균 방문 횟수(월): int // '횟수'는 소수점이 없는 정수. 3.5회 같은 값은 비즈니스 논리에 맞지 않음.

완성된 목록은 더 이상 단순한 데이터 타입의 나열이 아니었다. 각 데이터의 성격과 의도를 파악하고, 발생할 수 있는 오류를 미리 방지하려는 개발자의 고민과 판단이 담긴 ‘설계도’처럼 보였다.

솔라는 자신이 만든 결과물을 보며 미소 지었다. 자료형은 변수에 저장할 데이터의 종류와 크기를 정한다. 처음 그녀를 막막하게 했던 이 문장이 이제는 든든한 가이드라인으로 느껴졌다. 종류(성격, 의도)와 크기(표현 범위, 안전). 이 두 축을 기준으로 데이터를 바라보는 자신만의 프레임워크가 생긴 것이다. 이제 어떤 새로운 데이터를 만나더라도 당황하지 않고 자신만의 기준에 따라 최적의 그릇을 선택할 수 있을 것 같았다.