JavaScript의 기본적인 연산 - 숫자와 연산자

이 장은 JavaScript의 연산에 대해 다룹니다. 능숙하게 숫자를 다루기 위해 어떻게 연산자 와 그 외 기능을 사용하는지 알아봅니다.

필요한 사전 지식 기본적인 컴퓨터 지식, HTML과 CSS에 대한 기본적인 이해, JavaScript의 이해
목표 JavaScript 연산에 익숙해지기

모두가 수학을 좋아합니다

좋아요, 아닐수도 있습니다. 일부는 좋아하겠죠. 몇몇 사람들은 구구단을 배울 때부터 싫어했을 겁니다. 그리고 몇몇은 이 사이 어딘가 있겠죠. 그러나 누구도 수학이 삶을 살아가는데 필수적 요소라는건 부정할 수 없을겁니다. 우리가 JavaScript(또는 다른 프로그래밍 언어)를 배울 때 특히 그렇습니다. 우리가 하는 일의 상당 부분은 수치형 데이터를 처리하고, 값을 계산하거나 하는 일입니다.

이 장은 당장 알아야 하는 부분만 다룹니다.

숫자의 종류

프로그래밍에서는 우리가 잘 알고있는 십진법 체계도 생각보다 복잡합니다.

  • 정수는 10, 400, 혹은 -5 같은 모든 숫자입니다.
  • 부동소수점 실수(float)는 12.5, 6.7786543과 같이 소수점과 소수 자릿수가 있습니다.
  • 배정밀도 부동소수점 실수(double)는 IEEE 754 표준 부동소수점보다 더 정확한 정밀도를 가지고 있는 특별한 데이터 타입입니다. (DoublesFloats 보다 더 많은 소수 자릿수를 표현할 수 있어서 소수점 표현에는 Doubles가 더 정확합니다).

JavaScript는 심지어 다른 숫자 타입을 지원합니다. 10진수는 10을 기준으로 합니다. (숫자 0~9을 쓴다는 뜻입니다.) 하지만 JavaScript는 아래와 같은 데이터 타입을 지원합니다.

  • 2진수 — 10진수를 0과 1를 이용해 나타내는 데이터 타입입니다.
  • 8진수 — 10진수를 0부터 7까지의 수를 이용해 나타내는 데이터 타입입니다.
  • 16진수 — 10진수를 0부터 15까지의 수(1~10, A~F)를 이용해 나타내는 데이터 타입입니다. CSS의 색상을 지정할 때 쉽게 볼 수 있습니다.

어려워서 힘들다고 느끼기 전에, 잠시 멈추세요! 시작하기 위해서 우리는 이제부터 10진수만 사용하도록 하겠습니다. 다른 유형에 대해 생각할 필요가 없습니다.

두 번째 좋은 소식은 다른 프로그래밍 언어와 달리, JavaScript는 실수와 정수 모두 Number라는 하나의 데이터 타입만 사용합니다. 실수와 정수 모두 같은 데이터 타입이기 때문에 하나의 방법으로 동작하게 할 수 있다는 뜻입니다.

참고: 사실 JavaScript에는 BigInt라는 또 다른 숫자 타입이 있습니다. 정수를 나타내는 데 사용되는 데이터 타입이지만 이 글에서는 다루지 않습니다.

나를 위한 숫자들

우리가 필요한 기본 구문을 다시 익히기 위해 몇 가지 숫자를 빠르게 생각해 봅시다. developer tools JavaScript console (en-US) 에 들어가서 아래의 나열된 명령어를 입력해주세요.

  1. 먼저, 두 개의 변수를 선언합니다. 그리고 두 개의 변수를 정수와 실수로 초기화해줍니다. 각각 변수명을 콘솔 창에 입력해주세요. 그리고 어떤 값이 나오는지 확인해주세요.
    var myInt = 5;
    var myFloat = 6.667;
    myInt;
    myFloat;
    
  2. 숫자는 따옴표(" 또는 ')가 없습니다. 계속 하기 전에 여러 개의 변수를 선언하고 숫자를 초기화 해주세요.
  3. 우리들의 변수들의 데이터 타입을 확인합니다. JavaScript에서는 데이터 타입을 확인하기 위해 typeof 라는 키워드를 사용합니다. 아래와 같이 입력해 주세요:
    typeof myInt;
    typeof myFloat;
    
    "number" 는 정수와 실수인 경우에 나옵니다. — 이것들은 정수와 실수가 다른 데이터 타입일 때 보다 다루기 쉽게 해줍니다. 그리고 다른 데이터 타입일 때 다른 방법으로 다뤄야만 합니다. 호우~!

유용한 Number 메서드들

JavaScript에서 모든 표준 숫자를 나타내는 Number 객체에는 숫자를 조작하는 데 사용할 수 있는 많은 유용한 메서드가 있습니다. 간단한 소개만 하기 위해 이 문서에서는 이러한 메서드에 대해 자세히 설명하지 않고 기본적인 내용만 다룹니다. 하지만 객체 참조 페이지를 방문해서 사용 가능한 메서드에 대해 더 알아볼 가치는 있습니다.

예를 들어, 숫자를 고정된 소수점 자리수로 반올림하려면 toFixed() 메서드를 사용합니다. 다음 코드를 브라우저 콘솔에서 실행시켜 보세요.

const lotsOfDecimal = 1.766584958675746364;
lotsOfDecimal;

const twoDecimalPlaces = lotsOfDecimal.toFixed(2);
twoDecimalPlaces;

숫자 데이터 타입으로 변환하기

때로는 계산을 수행하기 어렵게 문자열 형식으로 숫자가 저장된 경우가 있습니다. 주로 입력 폼입력 타입이 텍스트 (en-US)인 경우에 발생합니다. 이러한 경우에는 문자열 값을 Number() 생성자로 전달하면 같은 숫자를 나타내는 숫자 데이터 타입으로 변환할 수 있습니다.

예를 들어, 콘솔에 다음과 같이 입력해보세요.

let myNumber = "74";
myNumber += 3;

실행하면 77이 아닌 743이 출력됩니다. 이는 myNumber가 문자열이기 때문입니다. 다음 코드를 입력하면 타입을 볼 수 있습니다.

typeof myNumber;

올바른 계산 결과를 얻기 위해서는 다음과 같이 하면 됩니다.

let myNumber = "74";
myNumber = Number(myNumber) + 3;

정상적으로 77이 출력됩니다.

산술 연산자

산술연산자들의 기본적인 용도는 덧셈을 할 때 입니다.

연산자 이름 목적 예시
+ 더하기 두 개의 숫자를 더합니다. 6 + 9
- 빼기 왼쪽에 있는 수를 오른쪽 수로 뺍니다. 20 - 15
* 곱하기 두 개의 숫자를 곱합니다. 3 * 7
/ 나누기 왼쪽의 숫자를 오른쪽 숫자로 나눠서 몫을 구합니다. 10 / 5
% 나머지 (또는 모듈로) 왼쪽의 숫자를 오른쪽 숫자로 나눠서 나머지를 구합니다. 8 % 3 ( 2를 반환합니다, 8을 3으로 나눴을 때 몫이 2이기 때문입니다.)
** 지수 왼쪽의 숫자를 오른쪽 숫자만큼 제곱합니다. 5 ** 2 ( 5의 제곱이기 때문에 25를 반환합니다.)

참고: 연산에 관계된 수를 피연산자라고 부릅니다.

참고: 지수를 계산할 때 Math.pow() 메서드를 사용할 수도 있고 **와 매우 비슷한 동작을 합니다. 예를 들어, Math.pow(7, 3)의 경우 7은 밑, 3은 지수이므로 343을 반환합니다. 이 결과는 7 ** 3과 같습니다.

아직 수학을 공부할 필요는 없습니다. 하지만 우리는 문법 확인을 해야합니다. 아래의 명령어들을 developer tools JavaScript console (en-US) 에 입력해주세요.

  1. 아래의 명령어를 콘솔창에 입력해주세요.
    10 + 7
    9 * 8
    60 % 3
    
  2. 또한 변수 내부의 값을 선언하거나 초기화 할 수 있으며, 이를 계산에 이용할 수도 있습니다. 즉, 변수는 계산을 위해 가지고 있는 값과 정확히 동일하게 작동합니다. 예를 들어
    const num1 = 10;
    const num2 = 50;
    9 * num1;
    num2 / num1;
    
  3. 마지막으로 다음과 같은 복잡한 식을 입력해보세요.
    5 + 10 * 3;
    num2 % 9 * num1;
    num2 + num1 / 8 + 2;
    

몇몇 계산은 예상과 꽤 다르게 나옵니다. 아래의 문단에서 왜 그런지 이유를 알아보죠.

연산자 우선순위

위의 예제를 살펴보겠습니다. 위와 동일하게 num250num110을 가지고 있다고 가정하겠습니다.

num2 + num1 / 8 + 2;

아마 "50 더하기 10은 60이고, 8 더하기 2는 10이니, 60 나누기 10은 6이다."라고 계산했을 겁니다.

하지만 브라우저는 "10 나누기 8은 1.25이고, 50 더하기 1.25 더하기 2는 53.25이다."라고 계산합니다.

이것은 연산자 우선순위 때문입니다. 연산자 우선순위는 어떤 연산자를 먼저 계산할지 결정합니다. JavaScript에서의 연산자 우선순위는 학교 수학 수업에서 배웠던 것과 같습니다. 곱하기와 나누기는 먼저 계산되고, 더하기와 빼기는 나중에 계산됩니다. (합은 항상 왼쪽에서 오른쪽으로 계산됩니다)

만약 연산자 우선순위를 무시하고 싶다면 괄호를 사용하여 먼저 계산할 부분을 지정할 수 있습니다. 다음과 같이 하면 6이라는 결과를 얻을 수 있습니다.

(num2 + num1) / (8 + 2);

참고: JavaScript의 연산자와 연산자 우선순위에 대해 더 알고 싶다면 표현식과 연산자 문서를 참고하세요.

증감 연산자

가끔은 반복해서 숫자 변수의 값을 1씩 더하거나 빼고 싶을 때가 있습니다. 이럴 때는 증가(++) 연산자와 감소(--) 연산자를 사용하면 편리합니다. 우리는 JavaScript 첫 입문 (en-US) 문서에서 guessCount 변수에 1씩 더해 사용자가 매 차례마다 남은 추측 횟수를 볼 수 있도록 했습니다.

guessCount++;

콘솔에서 이것을 사용해 보겠습니다. 우선, 숫자에 직접 쓸 수 없다는 것을 알아두세요. 이상하겠지만 값 자체를 계산하는 것이 아니라 변수에 새로운 업데이트된 값을 할당하는 것입니다. 다음은 오류를 반환합니다.

3++;

다음처럼 변수만 증가시킬 수 있습니다.

var num1 = 4;
num1++;

또 이상한 일이 일어났습니다! 이렇게 하면 4가 반환됩니다. 왜냐하면 브라우저가 현재 값을 반환한 뒤에 변수를 증가시키기 때문입니다. 변수 값을 다시 반환하면 증가했음을 알 수 있습니다.

num1;

--에서도 똑같이 작동합니다.

var num2 = 6;
num2--;
num2;

참고: 변수 앞에 연산자를 사용하면 브라우저가 변수를 먼저 증가/감소시키고 값을 반환합니다. 이번에는 ++num1--num2를 사용하고 위의 예제를 다시 실행해 보세요.

대입 연산자

대입 연산자는 변수에 값을 대입하는 연산자입니다. 우리는 이미 기본적인 = 연산자를 많이 사용했습니다. 이 연산자는 변수 오른쪽에 있는 값을 대입합니다.

var x = 3; // x의 값은 3입니다.
var y = 4; // y의 값은 4입니다.
x = y;     // 이제 x의 값은 y와 같은 4입니다.

추가로 코드를 더 깔끔하고 효율적으로 쓸 수 있게 해주는 짧은 형태의 연산자들이 있습니다. 대표적인건 다음과 같습니다.

연산자 이름 목적 예시 의미
+= 더하기 대입 오른쪽의 값을 왼쪽 변수 값에 더하고 새 변수 값을 반환합니다. x += 4; x = x + 4;
-= 빼기 대입 오른쪽의 값을 왼쪽 변수 값에서 빼고 새 변수 값을 반환합니다. x -= 3; x = x - 3;
*= 곱하기 대입 오른쪽의 값을 왼쪽 변수 값에 곱하고 새 변수 값을 반환합니다. x *= 3; x = x * 3;
/= 나누기 대입 오른쪽의 값을 왼쪽 변수 값에 나누고 새 변수 값을 반환합니다. x /= 5; x = x / 5;

위의 예제들을 콘솔에 입력해 보면서 어떻게 작동하는지 알아보세요. 그리고 두 번째 줄을 입력하기 전에 어떤 값이 나올지 예측해 보세요.

또한 오른쪽 표현식에서 다른 변수를 사용할 수 있습니다. 예를 들어

var x = 3; // x는 3입니다.
var y = 4; // y는 4입니다.
x *= y;    // 이제 x의 값은 12입니다.

참고: 더 많은 연산자가 있지만, 지금은 이것만 시용해도 충분합니다.

실전 예제: 캔버스 크기 바꾸기

이번 실습에서는 숫자와 연산자를 조작하여 박스의 크기를 바꿔보겠습니다. 박스는 Canvas API라는 브라우저 API를 사용하여 그려집니다. 이것이 어떻게 작동하는지는 신경 쓸 필요가 없습니다. 일단은 수학에 집중하세요. 박스의 너비와 높이(픽셀 단위)는 변수 xy에 의해 정의되며, 이 변수들은 처음에 각각 50의 값을 가집니다.

새 창에서 보기

이 예제에서는 주석으로 표시된 두 줄을 수정하여 박스의 크기를 특정 크기로 조정하고, 각각의 경우에 특정 연산자와/또는 값을 사용하도록 하겠습니다. 다음처럼 수정해 보세요.

  • x를 계산하는 줄을 변경하여 박스의 너비는 여전히 50px이지만, 50은 43과 7, 그리고 산술 연산자를 사용하여 계산되도록 합니다.
  • y를 계산하는 줄을 변경하여 박스의 높이는 75px이지만, 75는 25와 3, 그리고 산술 연산자를 사용하여 계산되도록 합니다.
  • x를 계산하는 줄을 변경하여 박스의 너비는 250px이지만, 250은 두 개의 숫자와 나머지(모듈로) 연산자를 사용하여 계산되도록 합니다.
  • y를 계산하는 줄을 변경하여 박스의 높이는 150px이지만, 150은 세 개의 숫자와 뺄셈과 나눗셈 연산자를 사용하여 계산되도록 합니다.
  • x를 계산하는 줄을 변경하여 박스의 너비는 200px이지만, 200은 숫자 4와 할당 연산자를 사용하여 계산되도록 합니다.
  • y를 계산하는 줄을 변경하여 박스의 높이는 200px이지만, 200은 숫자 50과 3, 곱셈 연산자, 그리고 덧셈 할당 연산자를 사용하여 계산되도록 합니다.

Reset 버튼을 눌러서 되돌릴 수 있기 때문에 코드가 동작하지 않아도 괜찮습니다. 위의 질문을 모두 통과했다면 코드를 자유롭게 수정하거나, 자신만의 도전을 해보세요.

비교 연산자

가끔은 참/거짓 테스트를 실행한 결과에 따라 다르게 처리하고 싶을 때가 있습니다. 이럴 땐 비교 연산자를 사용합니다.

연산자 이름 목적 예시
=== 일치 연산자 왼쪽과 오른쪽의 값이 완전히 동일한지 테스트합니다. 5 === 2 + 4
!== 불일치 연산자 왼쪽과 오른쪽 값이 서로 동일하지 않은지 테스트합니다. 5 !== 2 + 3
< ~보다 작음 왼쪽 값이 오른쪽 값보다 작은지 테스트합니다. 10 < 6
> ~보다 큼 왼쪽 값이 오른쪽 값보다 큰지 테스트합니다. 10 > 20
<= ~보다 작거나 같음 왼쪽 값이 오른쪽 값보다 작거나 같은지 여부를 테스트합니다. 3 <= 2
>= ~보다 크거나 같음 왼쪽 값이 오른쪽 값보다 크거나 같은지 여부를 테스트합니다. 5 >= 4

참고: 일부 사람들은 ==!=를 동등성과 불일치성을 테스트하는 데 사용합니다. 이 연산자들은 JavaScript에서 유효한 연산자이지만, ===/!==와는 다릅니다. 전자는 값이 동일한지는 테스트하지만, 값의 데이터 유형이 동일한지의 여부는 테스트하지 않습니다. 후자의 경우 엄격한 버전은 값과 값의 데이터 유형의 동일성을 모두 테스트합니다. 엄격한 버전이 오류가 적은 편이기 때문에, 이를 사용하는 것을 권장합니다.

만약 콘솔에 값들을 입력한다면 true/false 값이 반환되는걸 볼 수 있습니다. 이는 이전 글에서 본 것 처럼 불리언(boolean)입니다. 코드에서 결정을 내리거나, 어떤 선택을 할 때마다 사용하기 때문에 불리언은 상당히 유용합니다. 불리언을 사용하는 예는 다음과 같습니다.

  • 기능이 켜져있는지 꺼져있는지에 따라 버튼의 텍스트 라벨을 표시합니다.
  • 게임을 결과에 따라 게임 오버나 승리 메시지를 표시합니다.
  • 연휴에 따라 적절한 인사말을 표시합니다.
  • 확대 레벨에 따라 지도를 확대하거나 축소합니다.

지금은 간단한 예제를 살펴보고, 조건문은 다음 글에서 다뤄보겠습니다

<button>Start machine</button>
<p>The machine is stopped.</p>
var btn = document.querySelector('button');
var txt = document.querySelector('p');

btn.addEventListener('click', updateBtn);

function updateBtn() {
  if (btn.textContent === 'Start machine') {
    btn.textContent = 'Stop machine';
    txt.textContent = 'The machine has started!';
  } else {
    btn.textContent = 'Start machine';
    txt.textContent = 'The machine is stopped.';
  }
}

새 창에서 보기

updateBtn() 함수 내부에서 동등 연산자가 사용되는걸 볼 수 있습니다. 원리는 동일하지만, 이 경우엔 두 수식이 같은 값을 가지고 있는지 테스트하는 것이 아닌 버튼의 텍스트 콘텐츠가 특정 문자열을 포함하고 있는지를 테스트합니다. 버튼이 "Start machine"이라고 표시되어 있을 때 누르면 "Stop machine"으로 바꾸고 라벨을 변경합니다. 버튼이 "Stop machine"이라고 표시되어 있을 때 누르면 다시 표시를 바꿉니다.

참고: 위와 같은 두 상태를 전환하는 조작을 일반적으로 토글(toggle) 이라고 부릅니다.

요약

이번 글에서는 JavaScript에서 숫자를 다루는 기본적인 내용을 다뤘습니다. 앞으로도 숫자는 JavaScript를 배우는 동안 계속해서 사용할 것이므로 익숙해지는게 좋습니다. 수학을 좋아하지 않는 사람에겐 이번 글이 짧아서 다행이었겠군요.

다음 글에서는 텍스트와 JavaScript에서 텍스트를 조작하는 방법에 대해 알아보겠습니다.

참고: 만약 수학을 좋아하고 JavaScript에서 수학이 어떻게 구현되었는지에 대해 더 알고 싶다면, 숫자와 날짜표현식과 연산자를 참고하세요.

이 과정은