숫자와 문자열 다루기
Article
Part 2가 시작된다. 값의 종류를 알았으니, 이제 그 값으로 실제 일을 시킬 차례다.
가장 많이 쓰는 두 가지, 숫자와 문자열을 다룬다.
산술 연산자
수학에서 쓰던 것과 거의 같다. 두 개만 낯설 것이다.
| 기호 | 이름 | 예시 | 결과 |
|---|---|---|---|
| + | 덧셈 | 7 + 3 | 10 |
| - | 뺄셈 | 7 - 3 | 4 |
| * | 곱셈 | 7 * 3 | 21 |
| / | 나눗셈 | 7 / 3 | 2.333… |
| % | 나머지 | 7 % 3 | 1 |
| ** | 거듭제곱 | 7 ** 3 | 343 |
%는 백분율이 아니라 나머지다. 나눗셈을 하고 남은 값을 준다. 쓸모없어 보이지만 실제로는 자주 쓴다.
console.log(10 % 2);
console.log(7 % 2);
const number = 14;
console.log(number % 2 === 0);
- 0
- 1
- true
2로 나눈 나머지가 0이면 짝수다. 짝수·홀수 판별의 정석이다. 3으로 나눈 나머지로 세 칸씩 반복되는 패턴도 만들 수 있다.
계산해서 다시 넣기
변수의 값을 조금 바꿔 다시 넣는 일이 잦다. 그래서 짧게 쓰는 방법이 있다.
let count = 10;
count = count + 5;
count += 5;
console.log(count);
- 20
count += 5는 count = count + 5를 줄여 쓴 것이다. 다른 연산자도 같은 식으로 쓴다.
| 줄인 표현 | 원래 표현 |
|---|---|
| x += 3 | x = x + 3 |
| x -= 3 | x = x - 3 |
| x *= 3 | x = x * 3 |
| x /= 3 | x = x / 3 |
1씩 늘리고 줄이는 건 더 짧게 쓸 수 있다. 반복문에서 매번 보게 된다.
let n = 5;
n++;
console.log(n);
n--;
console.log(n);
- 6
- 5
0.1 + 0.2 는 0.3 이 아니다
3강에서 미뤄뒀던 이야기다. 직접 확인해본다.
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 === 0.3);
- 0.30000000000000004
- false
버그가 아니다. 자바스크립트만의 문제도 아니다. 파이썬, 자바, C 모두 같은 결과가 나온다.
이유는 컴퓨터가 숫자를 2진수로 저장하기 때문이다. 10진수 0.1을 2진수로 바꾸면 끝없이 반복되는 소수가 된다. 마치 10진수에서 1/3이 0.3333…으로 끝나지 않는 것과 같다.
- 01
0.1 을 2진수로 바꾼다
0.0001100110011001100… 처럼 무한히 반복된다. 딱 떨어지지 않는다.
- 02
정해진 자리에서 자른다
컴퓨터가 쓸 수 있는 공간은 유한하다. 어느 지점에서 반올림해 끊는다.
- 03
이미 0.1 이 아니다
저장된 값은 0.1 에 아주 가까운 다른 수다. 여기에 0.2 를 더하니 오차가 드러난다.
console.log(0.1 + 0.2); // 0.30000000000000004
그래서 어떻게 하나
소수를 비교할 때는 ===를 쓰지 않는다. 상황에 따라 두 가지 방법을 쓴다.
const price = 0.1 + 0.2;
console.log(price.toFixed(2));
console.log(Number(price.toFixed(2)) === 0.3);
console.log(Math.abs(price - 0.3) < Number.EPSILON);
- '0.30'
- true
- true
toFixed(2)는 소수점 아래 두 자리로 반올림한다. 다만 결과가 문자열이라는 함정이 있다. 위 출력에서 따옴표가 붙은 걸 보라. 다시 숫자로 쓰려면 Number()로 감싸야 한다.
돈처럼 정확도가 중요한 값은 아예 소수를 쓰지 않는 방법도 있다. 원 단위 대신 전부 정수로 다루는 식이다.
Math — 수학 도구 모음
자주 쓰는 계산은 Math에 모여 있다.
console.log(Math.round(4.5));
console.log(Math.floor(4.9));
console.log(Math.ceil(4.1));
console.log(Math.abs(-7));
console.log(Math.max(3, 9, 1));
console.log(Math.min(3, 9, 1));
- 5
- 4
- 5
- 7
- 9
- 1
세 가지 반올림을 헷갈리기 쉬우니 정리해둔다.
Math.round
가까운 정수로
4.4→44.5→5- 우리가 아는 반올림
Math.floor
무조건 내림
4.9→44.1→4- 바닥(floor)으로 내린다
Math.ceil
무조건 올림
4.1→54.9→5- 천장(ceiling)으로 올린다
Math.random()은 0 이상 1 미만의 무작위 수를 준다. 원하는 범위의 정수를 뽑을 때는 이렇게 조합한다.
const dice = Math.floor(Math.random() * 6) + 1;
console.log(dice);
- 4 (실행할 때마다 1~6 중 하나)
Math.random() * 6은 0 이상 6 미만이다. 내림하면 05가 되고, 1을 더해 16이 된다.
문자열의 길이와 위치
문자열은 글자가 순서대로 늘어선 것이다. 각 글자에는 번호가 붙는데, 0부터 시작한다.
- h0
- e1
- l2
- l3
- o4
const word = "hello";
console.log(word.length);
console.log(word[0]);
console.log(word[word.length - 1]);
console.log(word[99]);
- 5
- 'h'
- 'o'
- undefined
길이는 5인데 마지막 글자의 번호는 4다. 그래서 마지막 글자를 꺼내려면 length - 1을 쓴다. 이 하나 차이는 프로그래밍 내내 따라다니는 실수의 단골 원인이다.
없는 위치를 꺼내면 에러가 아니라 undefined가 나온다. 4강에서 본 "값이 아직 없음"이다.
문자열은 고칠 수 없다
글자 하나를 바꿔보려 하면 이상한 일이 벌어진다.
let word = "hello";
word[0] = "H";
console.log(word);
- hello
에러도 안 나고, 바뀌지도 않았다. 조용히 무시됐다.
자바스크립트에서 **문자열은 불변(immutable)**이기 때문이다. 한 번 만들어진 문자열은 절대 수정되지 않는다. 바꾸고 싶으면 새 문자열을 만들어 다시 대입해야 한다.
let word = "hello";
word = "H" + word.slice(1);
console.log(word);
- Hello
const name = "seoyeon";
name.toUpperCase();
console.log(name);
const upper = name.toUpperCase();
console.log(upper);
- seoyeon
- SEOYEON
자주 쓰는 문자열 메서드 맛보기
문자열 메서드는 수십 개라 외울 것이 아니라 필요할 때 찾아 쓰는 것이다. 자주 만날 것 몇 개만 봐둔다.
const text = " Hello World ";
console.log(text.trim());
console.log(text.trim().toLowerCase());
console.log(text.includes("World"));
console.log(text.trim().split(" "));
console.log("2025-01-26".replace(/-/g, "/"));
- 'Hello World'
- 'hello world'
- true
- ['Hello', 'World']
- '2025/01/26'
메서드를 점(.)으로 계속 이어붙일 수 있다. text.trim().toLowerCase()는 공백을 없앤 결과에 다시 소문자 변환을 적용한다. 앞의 결과가 뒤의 입력이 되는 구조다.
정리하면
%는 나머지 연산자다. 짝수·홀수 판별, 주기적 패턴에 쓴다.- 소수 계산에는 오차가 있다.
0.1 + 0.2 !== 0.3이다.===로 소수를 비교하지 않는다. toFixed()의 결과는 숫자가 아니라 문자열이다.- 문자열의 인덱스는 0부터 시작하고, 마지막 글자는
length - 1에 있다. - 문자열은 불변이다. 메서드는 원본을 고치지 않고 새 문자열을 돌려준다.
다음 강의에서는 값을 비교하고 판단하는 연산자를 다룬다. ==와 ===가 왜 둘 다 있는지, 왜 하나만 써야 하는지도 그때 본다.