숫자와 계산
자바스크립트에서 0.1 + 0.2는 0.30000000000000004이고, 17 % 5는 2입니다. 숫자를 어떻게 저장하는지, %가 무슨 뜻인지 알면 둘 다 이해가 됩니다.
산술 연산자
컴퓨터가 하는 일의 대부분은 결국 계산이고, 자바스크립트는 종이에 쓰는 것과 거의 같게 씁니다. 계산을 하는 기호를 연산자라고 합니다. 다섯 개는 이미 아는 것이고 두 개는 새로운 것입니다.
| 연산자 | 뜻 | 예 | 결과 |
|---|---|---|---|
| + | 더하기 | 7 + 2 | 9 |
| - | 빼기 | 7 - 2 | 5 |
| * | 곱하기 | 7 * 2 | 14 |
| / | 나누기 | 7 / 2 | 3.5 |
| % | 나머지 | 7 % 2 | 1 |
| ** | 거듭제곱 | 7 ** 2 | 49 |
곱하기는 별표를 씁니다. 글자 x를 쓰면 x라는 변수와 헷갈리기 때문입니다. 나누기는 언제나 소수까지 정확한 답을 냅니다. 7 / 2는 3이 아니라 3.5입니다. 나머지 연산자 %는 나눈 뒤 남는 것만 돌려줍니다. 17 % 5는 2인데, 17에 5가 세 번(15) 들어가고 2가 남기 때문입니다. 별것 아닌 것 같아도 프로그래밍에서 가장 많이 쓰는 연산자 가운데 하나입니다. n % 2가 0이면 n은 짝수이고, minutes % 60은 시간 단위를 뺀 나머지 분을 알려 줍니다.
계산 순서
자바스크립트의 계산 순서는 학교 수학과 같습니다. 거듭제곱이 먼저, 그다음 곱하기, 나누기, 나머지, 마지막에 더하기와 빼기입니다. 순위가 같은 연산자는 왼쪽에서 오른쪽으로 계산하는데, **만은 오른쪽에서 왼쪽으로 계산합니다. 괄호는 무엇보다 먼저이니 헷갈리면 괄호를 치세요. 손해 볼 것이 없고 다음에 읽는 사람에게 의도가 분명해집니다.
console.log(2 + 3 * 4); // 14
console.log((2 + 3) * 4); // 20
console.log(20 - 6 / 2); // 17
console.log(2 ** 3 * 5); // 40변수를 바꾸는 줄임 표기
변수에 자기 값을 써서 새 값을 넣는 일은 아주 흔해서 줄임 표기가 있습니다. x += 5는 x = x + 5와 같고, 같은 방식으로 -=, *=, /=도 있습니다. 정확히 1을 더하거나 뺄 때는 더 짧게 x++(1 더하기), x--(1 빼기)를 씁니다. ++는 반복문에서 계속 보게 됩니다.
let coins = 10;
coins += 5; // 15
coins *= 2; // 30
coins--; // 29
console.log(coins); // 29Math 도구
자바스크립트에는 Math라는 내장 객체가 있어서 숫자 도구를 바로 쓸 수 있습니다. Math.round(2.5)는 가장 가까운 정수로 반올림하고(3), Math.floor(2.9)는 언제나 내리며(2), Math.ceil(2.1)은 언제나 올립니다(3). Math.max(4, 9, 2)는 가장 큰 값을, Math.min은 가장 작은 값을 줍니다. Math.sqrt(81)은 제곱근 9이고, Math.PI는 원주율 π로 약 3.14159입니다. Math.floor와 %는 함께 쓰기 좋습니다. 135분이면 Math.floor(135 / 60)은 2시간, 135 % 60은 15분입니다.
0.1 + 0.2가 딱 0.3이 아닌 이유
자바스크립트는 ECMAScript 표준이 정한 대로 모든 숫자를 IEEE 754 배정밀도 형식으로 저장합니다. 정해진 크기의 이진수라는 뜻입니다. 0.1 같은 평범한 소수 중 일부는 이진수로 정확히 쓸 수 없습니다. 1/3을 십진 소수로 정확히 쓸 수 없는 것과 같습니다. 이 작은 반올림 오차는 보통 드러나지 않지만 가끔 보입니다. 0.1 + 0.2는 0.30000000000000004를 출력합니다. 코드가 틀린 것이 아닙니다. 돈이나 측정값을 사람에게 보여 줄 때는 (0.1 + 0.2).toFixed(2)처럼 반올림하면 문자열 "0.30"이 나옵니다. 정수는 약 9천조까지 정확히 저장되므로 수를 세는 데는 문제가 없습니다.
풀이 예시
예 1. 80, 90, 85의 평균은 (80 + 90 + 85) / 3입니다. 괄호가 없으면 80 + 90 + 85 / 3은 85만 나눠서 약 198.3이 됩니다. 예 2. 2024는 4의 배수일까요? 2024 % 4가 0이므로 그렇습니다. 예 3. 사탕 50개를 아이 6명에게 나누면 Math.floor(50 / 6)으로 한 명에 8개, 50 % 6으로 2개가 남습니다.
| 연산자 | 값을 계산하는 기호. + - * / % ** |
| % | 나눗셈의 나머지. 17 % 5는 2 |
| ** | 거듭제곱. 2 ** 3은 8 |
| += | x += 5는 x = x + 5 |
| ++ | 변수에 정확히 1을 더함 |
| Math.floor | 정수로 내림 |
| Math.round | 가장 가까운 정수로 반올림 |
| toFixed(2) | 숫자를 소수 둘째 자리까지 문자열로 표시 |
- 무엇이 출력될까요?
console.log(2 + 3 * 4); - 무엇이 출력될까요?
console.log((2 + 3) * 4); - 무엇이 출력될까요?
console.log(17 % 5); - 무엇이 출력될까요?
console.log(9 / 2); - 무엇이 출력될까요?
console.log(2 ** 5); - 무엇이 출력될까요?
let x = 10; x += 4; x *= 2; console.log(x); - 무엇이 출력될까요?
let n = 5; n++; n++; n--; console.log(n); - 무엇이 출력될까요?
console.log(Math.floor(7.9), Math.ceil(7.1));- 8 8
- 7 8
- 7 7
- 무엇이 출력될까요?
console.log(Math.max(3, 11, 6) - Math.min(3, 11, 6)); - 무엇이 출력될까요?
console.log(10 - 4 - 3); - 모든 짝수 n에 대해 참인 식은?
n % 2 === 0n / 2 === 0n % 2 === 1
- 무엇이 출력될까요?
console.log((0.1 + 0.2).toFixed(2));
- + - * /는 수학과 같고, /는 소수까지 줍니다.
- %는 나머지이고, n % 2 === 0이면 n은 짝수입니다.
- **는 거듭제곱입니다. 괄호, **, * / %, + - 순서로 계산합니다.
- x += 5와 x++는 x를 바꾸는 줄임 표기입니다.
- Math.floor, Math.round, Math.ceil, Math.max, Math.min, Math.PI.
- 소수에는 작은 반올림 오차가 있을 수 있으니 보여 줄 때는 toFixed를 씁니다.