본문으로 건너뛰기

사칙 계산과 나머지

자바스크립트 목차수와 글자레슨 8 / 76

목차

자바스크립트는 +·-·*·/로 사칙 계산을 합니다. 나눗셈의 몫은 Math.floor()로 소수점 아래를 내려 얻고, 나머지는 %로 따로 구합니다.

거스름돈 7300원을 천 원짜리 몇 장과 남는 돈으로 나눠 준다고 해 봅시다. 계산기처럼 7300을 1000으로 나누면 7.3이 나올 뿐, '7장과 300원'은 나오지 않습니다. 몫과 나머지를 따로 구하는 계산이 필요합니다.

8단계 중 1단계. 1번 줄 console.log(7 / 2)는 무엇을 찍을까요?

1사칙 계산과 계산 차례

+는 더하기, -는 빼기, *는 곱하기, /는 나누기입니다. 곱하기 기호는 ×가 아니라 별표 *입니다.

연산이 섞이면 수학과 같은 차례로 계산합니다. 괄호 안이 먼저, 그다음 곱하기·나누기, 마지막이 더하기·빼기입니다. 곱하기·나누기끼리, 더하기·빼기끼리는 왼쪽부터 계산합니다.

console.log(4000 + 4500);
console.log(10000 - 4000 * 2);
console.log((10000 - 4000) * 2);
console.log(10 - 4 - 3);
실행 결과
8500
2000
12000
3

2번 줄은 4000 * 2를 먼저 해 8000을 만든 뒤 10000에서 뺍니다. 3번 줄은 괄호 안을 먼저 계산해 6000에 2를 곱합니다. 4번 줄은 왼쪽부터 10 - 4가 6, 6 - 3이 3입니다. 어떤 식이든 이 차례로 끝까지 계산된 뒤 값 하나가 됩니다(규칙 2). 거듭제곱은 **입니다. 2 ** 3은 2를 세 번 곱한 8이고, 곱하기보다 먼저 계산합니다.

2나누기(/)는 소수점 아래까지

자바스크립트의 수는 한 종류(number)라서, 나누기 /도 나머지를 버리지 않고 소수점 아래까지 계산한 수 하나를 냅니다.

console.log(7 / 2);
console.log(6 / 2);
console.log(7300 / 1000);
실행 결과
3.5
3
7.3

나누어떨어지는 6 / 2는 3으로 찍히고, 나누어떨어지지 않으면 3.5나 7.3처럼 소수점 아래가 붙습니다. 3도 3.5도 같은 수 종류입니다.

소수점 아래가 있는 수는 컴퓨터가 2진수로 담기 때문에 아주 작은 오차가 생길 수 있습니다. 0.1 + 0.2는 0.3이 아니라 0.30000000000000004입니다. 그래서 이 과목은 가격처럼 딱 맞아야 하는 값을 정수(원 단위)로 씁니다.

3몫은 Math.floor, 나머지는 %

나눗셈을 몫과 나머지로 나누려면 Math.floor()와 %를 씁니다. Math.floor()는 괄호 안의 수에서 소수점 아래를 내린 정수를 돌려줍니다. floor는 '바닥'이라는 뜻이고, Math는 자바스크립트에 들어 있는 수학 도구 묶음의 이름입니다. %는 나눗셈의 나머지를 냅니다.

console.log(Math.floor(7 / 2));
console.log(7 % 2);
console.log(Math.floor(-7 / 2));
실행 결과
3
1
-4

7을 2로 나누면 몫이 3, 나머지가 1입니다. 3번 줄의 Math.floor()는 '내림'이라 수직선에서 왼쪽, 곧 더 작은 쪽의 정수로 갑니다. -3.5의 왼쪽 정수는 -3이 아니라 -4입니다. %는 곱하기·나누기와 같은 차례라, 식에 섞이면 더하기·빼기보다 먼저 계산합니다. 거스름돈도 같은 방법으로 나눕니다. 7300을 1000으로 나눈 몫 7은 천 원짜리 장 수, 나머지 300은 남는 돈입니다(1000 × 7 + 300 = 7300). 코드는 아래 예제에 있습니다.

40으로 나누어도 멈추지 않는다

수학에서는 0으로 나눌 수 없습니다. 모임 비용 12000원을 사람 수로 나누는데 사람 수가 0이면 무엇이 찍힐까요?

const cost = 12000;
const people = 0;
console.log(cost / people);
console.log(0 / people);
실행 결과 보기
실행 결과
Infinity
NaN

예상과 다르면 그곳이 배울 곳입니다. 자바스크립트는 0으로 나눠도 오류로 멈추지 않습니다. 3번 줄은 '끝없이 큼'을 뜻하는 수 Infinity를, 4번 줄의 0 / 0은 '수가 아님' NaN을 냅니다. Infinity와 NaN도 수 종류의 값이라 다음 계산으로 그대로 넘어갑니다.

계산 결과가 이상하면 찍어 보고, 나누는 수가 어디서 0이 됐는지 앞줄을 봅니다. 찍어 보며 틀린 값이 처음 생긴 줄을 찾는 법은 값을 찍어 보며 고치기 레슨에서 배웁니다.

예제

거스름돈 7300원을 천 원짜리와 남는 돈으로 나눕니다. '계산해 찍기'는 값 두기 → 계산하기 → 찍기 세 걸음으로 쓰고, 걸음마다 주석 머리줄을 답니다.

// 1. 값 두기
const change = 7300;
// 2. 계산하기
let bills = change / 1000;
bills = Math.floor(bills);
const rest = change % 1000;
// 3. 찍기
console.log('천 원', bills);
console.log('남는 돈', rest);
실행 결과
천 원 7
남는 돈 300

4번 줄은 이름 bills를 7.3, 곧 천 원짜리로 센 7.3장에 붙입니다. 5번 줄은 Math.floor()가 소수점 아래를 내린 새 값 7을 만들고, bills를 그 값으로 옮겨 붙입니다(규칙 3). 다시 붙일 이름이라 let으로 만들었습니다. 6번 줄의 rest는 천 원짜리 7장을 내고 남은 300입니다. 2번 줄의 change처럼 처음에 한 번 값을 두고 다시 붙이지 않는 이름을 고정값이라고 합니다. 다른 거스름돈을 나누려면 이 한 줄만 고치면 됩니다.

자주 틀리는 곳

틀린 생각: /는 몫을 낸다.

초등학교에서 배운 '몫과 나머지' 나눗셈 습관으로 7 / 2를 3으로 읽기 쉽지만, /는 소수점 아래까지 나눕니다.

console.log(7 / 2);
console.log(Math.floor(7 / 2));
실행 결과
3.5
3

1번 줄의 /는 3.5를 내고, 몫 3은 2번 줄처럼 Math.floor()로 소수점 아래를 내려야 나옵니다.

맞는 규칙: 자바스크립트의 수는 한 종류라 /는 소수점 아래까지 나눈 수를 냅니다. 장 수나 시간처럼 몫이 필요하면 Math.floor()로 내립니다.

틀린 생각: Math.floor()는 소수점 아래를 떼어 버린다.

양수에서는 Math.floor(3.5)가 3이라 소수점 아래를 떼는 것처럼 보이지만, 음수에서는 결과가 달라집니다.

console.log(Math.floor(3.5));
console.log(Math.floor(-3.5));
실행 결과
3
-4

-3.5에서 소수점 아래를 떼면 -3이지만, Math.floor()는 -4를 냅니다.

맞는 규칙: Math.floor()는 그 수보다 크지 않은 가장 큰 정수, 곧 수직선에서 그 수나 바로 왼쪽의 정수를 냅니다. 그래서 음수는 더 작은 쪽으로 내려가고, 정수는 그대로입니다.

틀린 생각: 소수가 섞인 계산도 종이에서처럼 딱 떨어진다.

종이에서는 3200원의 1.1배가 정확히 3520원이지만, 컴퓨터로 계산하면 끝자리에 꼬리가 붙을 수 있습니다.

console.log(3200 * 1.1);
console.log(10000 * 1.1);
실행 결과
3520.0000000000005
11000

같은 1.1배인데 3200은 꼬리가 붙고 10000은 딱 떨어집니다. 어느 값에 꼬리가 붙는지는 찍어 보기 전에 알기 어렵습니다.

맞는 규칙: 컴퓨터는 소수를 2진수로 담아 아주 작은 오차가 생길 수 있습니다. 그래서 돈처럼 딱 맞아야 하는 값은 정수(원 단위)로 계산합니다.

확인 문제

1. 예제의 2번 줄을 const change = 4900;으로 바꿨습니다. 무엇이 찍힐까요? 글자 그대로 쓰세요.

// 1. 값 두기
const change = 4900;
// 2. 계산하기
let bills = change / 1000;
bills = Math.floor(bills);
const rest = change % 1000;
// 3. 찍기
console.log('천 원', bills);
console.log('남는 돈', rest);
힌트

'2. 계산하기'의 세 줄을 차례로 따라가며 이름마다 붙는 값을 적어 보세요.

정답
실행 결과
천 원 4
남는 돈 900

bills는 먼저 4.9에 붙고, Math.floor()가 소수점 아래를 내린 4로 옮겨 붙습니다. 4900을 1000으로 나눈 나머지 rest는 900입니다.

흔한 오답은 천 원 5입니다. 4.9를 반올림한다고 본 것입니다. Math.floor()는 늘 아래로 내립니다.

2. 예제의 '2. 계산하기'에서 한 줄을 비웠습니다. 결과가 예제와 똑같이 천 원 7과 남는 돈 300으로 찍히도록 빈칸을 채우세요.

// 1. 값 두기
const change = 7300;
// 2. 계산하기
let bills = change / 1000;
bills = Math.floor(bills);
const rest = ____;
// 3. 찍기
console.log('천 원', bills);
console.log('남는 돈', rest);
힌트

rest는 천 원짜리를 내고 남는 돈입니다. 나눗셈의 나머지를 내는 기호를 떠올려 보세요.

정답

change % 1000입니다. 채우면 예제와 같은 코드가 되어 같은 두 줄을 찍습니다.

change - bills * 1000⁠도 같은 300을 만들어 맞습니다. 300처럼 수를 직접 써도 같은 화면이 찍히지만, 2번 줄의 change를 바꾸면 따라 바뀌지 않습니다.

흔한 오답은 change / 1000입니다. 그러면 rest가 7.3에 붙어 남는 돈 7.3이 찍힙니다.

3. 걸린 시간 135분을 시간과 분으로 나눠 봅니다. 무엇이 찍힐까요? 세 줄을 글자 그대로 쓰세요.

const minutes = 135;
const hours = minutes / 60;
console.log(Math.floor(hours));
console.log(minutes % 60);
console.log(hours);
힌트

135분이 몇 시간 몇 분인지 먼저 생각하세요. 그다음 줄마다 쓰인 것(Math.floor() · % · 그대로)을 견주어 보세요.

정답
실행 결과
2
15
2.25

hours는 135를 60으로 나눈 2.25입니다. 3번 줄은 그것을 내려 2시간, 4번 줄은 60으로 나눈 나머지 15분입니다. 5번 줄은 hours를 그대로 찍어 2.25입니다.

흔한 오답은 셋째 줄의 2.15입니다. 2시간 15분을 그대로 소수처럼 적은 것입니다. 2.25는 2시간과 0.25시간(15분)입니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 예제(거스름돈 나누기)를 main.js에 저장해 돌립니다. 그다음 2번 줄의 7300을 다른 값(예: 12800)으로 바꾸면 두 줄이 무엇을 찍을지 먼저 적고, 바꿔 돌려서 맞춰 봅니다. 저장하고 돌리는 법은 내 컴퓨터에서 돌려 보기에 있습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

자바스크립트 목차로