본문 바로가기
Javascript study

[Javascript] 기본 연산자와 수학

by 카누가 좋아요 2023. 7. 6.

📌 참고 사이트

기본 연산자와 수학 (javascript.info)

기본 연산자와 수학

ko.javascript.info

 
 
 

📋 연산자에 대한 용어

➡️ 피연산자(operand, 인수) : 연산자가 연산을 수행하는 대상
ex) 5 * 2 → 왼쪽 피연산자 5, 오른쪽 피연산자 2
➡️ 단항(unary) 연산자 : 피연산자를 하나만 받는 연산자
ex) - (단항 마이너스 연산자) → -x와 같은 경우
➡️ 이항 (binary) 연산자 : 두 개의 피연산자를 받는 연산자
ex) 1 - 3 → 여기에서 -는 이항 마이너스 연산자 (피연산자의 개수가 1, 3 2개이므로 위의 단항 마이너스 연산자와는 다름)
 
 
 

📋 수학 연산자

자바스크립트에서 지원하는 수학 연산자에는
덧셈 연산자 (+), 뺄셈 연산자 (-), 곱셈 연산자 (*), 나눗셈 연산자 (/), 나머지 연산자 (%), 거듭제곱 연산자 (**)
가 있다.
 

📍 나머지 연산자 %

a % b를 수행하면 a를 b로 나눈 후 그 나머지를 정수로 반환해 준다.
 

alert(5 % 2);     // 5를 2로 나눈 후의 나머지인 1 출력
alert(8 % 3);     // 8을 3으로 나눈 후의 나머지인 2를 출력

 

📍 거듭제곱 연산자 **

a ** b를 평가하면 다음과 같다.
➡️ b가 양수일 경우 a를 b번 곱한 값이 반환된다.
➡️ b가 음수일 경우에는 a의 역수를 b번 곱하는 방식으로 계산된다.
➡️ b가 정수가 아닌 숫자일 경우 a의 n제곱근 형태로 계산된다.
 

alert(2 ** 2);     // 4 (2 * 2)
alert(2 ** 3);     // 8 (2 * 2 * 2)
alert(2 ** 4);     // 16 (2 * 2 * 2 * 2)

alert(4 ** (1/2));     // 2 (4의 제곱근)
alert(8 ** (1/3));     // 2 (8의 세제곱근)

 
 
 

📋 이항 연산자 '+'와 문자열 연결

➡️ 이것은 JS에서 제공하는 특별한 연산자 기능이다.
➡️ 덧셈 연산자 (+)는 대개 숫자를 더한 결과를 반환하지만 이항 연산자 (+)의 피연산자로 문자열이 전달되면 덧셈 연산자는 덧셈이 아닌 문자열을 병합한다.
(피연산자 중에 하나만 문자열이어도 다른 하나도 문자열로 변환된다.)
➡️ 계산은 왼쪽에서 오른쪽으로 순차적으로 이루어지므로 두 개의 숫자 뒤에 문자열이 오는 경우에는 숫자가 먼저 더해지고, 그 후에 더해진 숫자와 문자열과의 병합이 일어난다.
➡️ 다른 산술 연산자(-, / 등)의 경우에는 오직 숫자형의 피연산자만 다루고, 피연산자가 숫자형이 아닐 경우 그 형을 숫자형으로 바꾼다. (+와 대조적)
 

// 이항 연산자 +의 피연산자 2개 모두 문자열일 경우
let s = "my" + "string";
alert(s);     // mystring

// 이항 연산자 +의 피연산자 중 1개가 문자열일 경우
alert('1' + 2);     // 12
alert(2 + '1');     // 21

// 복잡한 예시
alert(2 + 2 + '1');     // 41

// 다른 피연산자 예시
alert(6 - '2');     // 4 ('2'를 숫자로 바꾼 후 연산이 진행된다.)
alert('6' / '2');     // 3 (두 피연산자가 숫자로 바뀐 후 연산이 진행된다.)

 
 
 

📋 단항 연산자 +와 숫자형으로의 변환

➡️ 숫자단항 덧셈 연산자를 붙이면 아무런 동작도 하지 않는다.
➡️ 피연산자가 숫자가 아닌 경우에는 숫자형으로의 변환이 일어난다.
(즉, Number 함수와 동일한 역할을 해준다.)
 

// 숫자에 단항 덧셈 연산자를 적용하면 아무 동작도 하지 않는다.
let x = 1;
alert(+x);     // 1

let y = -2;
alert(+y)     // -2

// 숫자형이 아닌 피연산자는 숫자형으로 변화한다.
alert(+true);     // 1
alert(+"");     // 0

 
➡️ 활용 : HTML 폼(form) 필드에서 값을 가져오는 데 그 값이 문자형일 경우 덧셈 연산자를 사용하면 피연산자를 손쉽게 숫자형으로 변화시킬 수 있다.
 

let two = "2";
let three = "3";

// 이항 덧셈 연산자의 경우 문자열을 연결한다.
alert(two + three);     // "23"

// 단항 덧셈 연산자를 적용하면 이항 덧셈 연산자가 적용되기 전에 두 피연산자는 숫자형으로 변화한다.
alert(+two + +three);     // 5

 

위에서 +two와 +three는 Number(two)와 Number(three)로도 작성이 가능하지만 코드가 더 길어진다.
또, 이항 연산자 +보다 단항 연산자 +가 먼저 적용되는 이유는 '연산자 우선순위' 때문이다.
 
 
 

📋 연산자 우선순위

➡️ 하나의 표현식에 둘 이상의 연산자가 있는 경우, 실행 순서연산자의 우선순위에 위해 결정된다.
 
<연산자 우선순위표 (순위 숫자가 클수록 우선순위가 높은 것임.)>
 

순위연산자 이름기호
...............
3할당=
...............
13뺄셈 , 덧셈- , +
15곱셈 , 나눗셈* , /
16지수**
17단항 덧셈, 단항 부정 +, -
...............

 
단항 덧셈 연산자가 우선순위 17로, 이항 덧셈 연산자의 우선순위인 13보다 높다. 따라서 위 +two + +three에서 +two와 +three가 먼저 수행되게 된다.
 
➡️ 괄호 ( ) 의 경우 모든 연산자보다 우선순위가 높기 때문에 JS에서 정의한 연산자 우선순위를 무력화시킨다. 따라서 우선순위가 헷갈린다면 괄호를 사용하여 식을 작성하면 된다.
ex) 1 + 2 * 2의 식을 1 + (2 * 2) 이렇게 작성
 
 
 

📋 할당 연산자

➡️ 어떠한 값을 변수에 할당할 때 쓰이는 할당 연산자 =도 연산자이다.
➡️ 우선순위 표에서 우선순위가 3으로 아주 낮다.
ex) x = 2 * 2 + 1에서 숫자의 연산이 먼저 이루어지고 마지막에 x로의 할당이 일어난다.
 

📍 값을 반환하는 할당 연산자

➡️ 할당 연산자 = 는 값을 반환한다. (JS에서 +, - 같은 모든 연산자들은 값을 반환한다.)
x = value에서 value는 x에 할당되고 이에 더해 value가 반환되는 식이다.
 

let a = 1;
let b = 2;

let c = 3 - (a = b + 1);

alert(a);     // 3
alert(c);     // 0

 

위 코드에서 (a = b + 1)은 a에 값을 할당하고, 그 값인 3을 반환한다. 그리고 반환 값은 이어지는 표현식에 사용된다. 따라서 c = 3 - 3이 된다.
여러 자바스크립트 라이브러리에서 이러한 식으로 할당 연산자를 사용하고 있으므로 동작 원리를 이애할 수 있어야 한다. 
but 직접 코드 작성 시에는 가독성이 떨어지므로 권장하지 않는다.
 

📍 할당 연산자 체이닝

➡️ 할당 연산자여러 개를 연결하여 사용하는 것이 가능하다.
➡️ 할당 연산자 체이닝이 일어나면 평가는 우측부터 진행되고, 그 결과가 좌측에 순차적으로 할당된다. 결과적으로 모든 변수가 같은 값을 가지게 된다.
(but 이번에도 가독성을 위해 줄을 나누어 코드를 작성하는 것이 권장된다.)
 

let a, b, c;

// 할당 연산자 체이닝
a = b = c = 2 + 2;     // 2 + 2 계산 -> c에 할당 -> b에 할당 -> a에 할당

alert(a);     // 4
alert(b);     // 4
alert(c);     // 4

 

📍 복합 할당 연산자

➡️ 변수에 연산자를 적용하고 그 결과를 같은 변수에 저장해야 하는 경우 복합 할당 연산자를 사용해 간결하게 코드를 작성할 수 있다.
ex) +=, *=, /=, -= 등
 

let n = 2;

n += 5;     // 7 (n = n + 5와 같음.)
n *= 2;     // 14 (n = n * 2와 같음.)

alert(n)     // 14

 

➡️ 복합 할당 연산자의 우선순위할당 연산자와 동일 (우선순위가 낮음)하여 대부분 다른 연산자가 실행된 후에 복합 할당 연산자가 실행된다.
 

let n = 2;

n *= 3 + 5;     // *=의 우측이 먼저 평가되므로 이항 연산자 + 먼저 실행 후 *= 적용

alert(n);     // 16

 
 
 

📋 증가, 감소 연산자

JS에서는 숫자를 하나 늘리거나 줄이는 연산을 해 주는 연산자를 제공한다.
➡️ 증가 연산자 (++) : 변수를 1 증가시킨다.
➡️ 감소 연산자 (--) : 변수를 1 감소시킨다.
❗ 증감 연산자는 변수에만 사용할 수 있다. 숫자에 직접적으로 적용하려 하면 에러가 발생한다.
 
++와 --는 변수 앞, 뒤에 오는 것이 모두 가능하다.
➡️ 후위형 (postfix form) : 피연산자 뒤에 증감 연산자가 오는 경우     ex) counter++
증가 or 감소 전의 기존 값을 반환한다. 따라서 1 증가 or 감소는 다음 번에 증감 연산자가 적용되었던 변수에 접근할 때 적용되어 있다. (아래에서는 반환 값을 확인하기 위해 새로운 변수에 값을 넣어줌.)
→ 따라서 값을 증감시키지만, 증감 전의 기존 값을 사용하려면 후위형 증감 연산자를 사용하면 된다.
 

let counter = 1;

// 후위형 (counter를 증가 or 감소시키기 전의 기존 값 반환)
let a = counter++;
let b = counter--;

alert(a);     // 1
alert(b);     // 1

 
➡️ 전위형 (prefix form) : 피연산자 앞에 증감 연산자가 오는 경우     ex) ++counter
증가 or 감소 전의 기존 값을 반환한다. 따라서 전위 연산자가 적용된 순간부터 값이 1 증가 or 감소되어 잇다.
→ 따라서 값을 증감시키고 난 후 그 증감된 값을 바로 사용하려면 전위형 증감 연산자를 사용하면 된다.
 

let counter = 1;

// 전위형 (counter를 증가 or 감소시킨 후 새로운 값 반환)
let a = ++counter;
let b = --counter;

alert(a);     // 2
alert(b);     // 0

 
💡 후위형과 전위형은 피연산자를 1만큼 증가 or 감소시켜 준다는 점에서 동일한 일을 하지만 차이는 위와 같이 반환 값에서 드러난다. (앞에서 모든 연산자는 값을 반환한다고 배웠다.)
 
➡️ 반환 값을 사용하지 않는 경우에는 전위형과 후위형의 결과에는 차이가 없다.
 

let counter = 0;
counter++;     // 후위이므로 0 반환 but 아래에서 counter 변수 활용 시 1 증가된 1 적용
++counter;     // counter 변수 1 증가하여 2, 전위이므로 1 증가된 2 반환
alert(counter)     // 2, 위 두 라인은 동일한 연산 수행

 
➡️ ++, -- 연산자를 표현식 중간에 사용하는 것도 가능하다. 이때, 증감 연산자의 우선순위는 다른 대부분의 산술 연산자보다 높으므로 평가가 먼저 이루어진다.
(but 이 경우에도 가독성을 위해 코드 한 줄에는 특정 동작 하나에 관련된 내용만 작성하는 것이 좋다.)
 

let counter = 1;
alert(2 * ++counter);     // 4 (2 * 2)
// 위 경우 ++counter (전위형)는 1 증가된 값을 반환하므로 2를 반환

let counter = 1;
alert(2 * counter++);     // 2 (2 * 1)
// 위 경우 counter++ (후위형)는 기존 값을 먼저 반환하고 1 증가시키므로 1을 반환

 
 
 

📋 비트 연산자

➡️ 인수를 32비트 정수로 변환하여 이진 연산을 수행한다.
➡️ JS뿐만 아니라 대부분의 프로그래밍 언어에서 지원한다.
➡️ 비트 연산자는 저수준(2진 표현)에서 숫자를 다뤄야 할 때 쓰이므로 흔하게 쓰이지는 않는다. but 암호를 다뤄야 할 땐 비트 연산자가 유용하다.
 
<비트 연산 시 쓰이는 연산자 목록>
 

비트 연산자기호
비트 AND&
비트 OR|
비트 XOR^
비트 NOT~
왼쪽 시프트 (LEFT SHIFT)<<
오른쪽 시프트 (RIGHT SHIFT)>>
부호 없는 오른쪽 시프트 (ZERO-FILL RIGHT SHIFT)>>>

 
 
 

📋 쉼표 연산자

➡️ 쉼표 연산자 ,는 코드를 짧게 쓰려는 의도로 가끔 사용되고, 여러 자바스크립트 프레임워크에서 볼 수 있다.
➡️ 여러 표현식을 코드 한 줄에서 평가할 수 있게 해준다. 표현식 각각이 모두 평가되지만, 마지막 표현식의 평과 결과만 반환된다.
➡️ 쉼표 연산자의 우선순위는 매우 낮다. (할당 연산자보다 더 낮음.) 
 

let a = (1 + 2, 3 + 4);
alert(a);     // 7 (3 + 4의 결과)

 

위 예시의 경우 첫 번째 표현식 1 + 2는 평가가 되지만 그 결과는 버려진다. 마지막인 3 + 4만 평가되어 a에 할당된다.
만약 위 예시에서 괄호가 없다면 a = 1 + 2, 3 + 4 에서 +가 먼저 수행되어 a = 3, 7이 되고, 할당 연산자가 먼저 실행되어 a = 3이 되고, 7은 무시되게 된다. 결국 a = (1 + 2), 3 + 4를 연산한 것처럼 된다.
 
<쉼표 연산자의 활용>
 

// 한 줄에서 3개의 연산이 수행된다.
// a와 b 자체가 버려지는 것이 아니라 반환되는 값이 c의 값인 것이다.
for  (a = 1, b = 3, c = a * b; a < 10 ; a++) {
    ...
}

 

but 쉼표 연산자는 코드 가독성에 도움이 되지 않으므로 진짜 필요한 경우에만 사용해야 한다.
 
 
 

✏️ 과제

📍 전위형과 후위형

아래 코드가 실행된 후,  변수 a, b, c, d에는 각각 어떤 값들이 저장될까?
 

let a = 1, b = 1;

let c = ++a;     // 변수 c에는 2가 저장된다. (전위형의 경우 1 증가된 값이 반환됨.)
let d = b++;     // 변수 d에는 1이 저장된다. (후위형의 경우 기존 값 반환 후 1 증가됨.)

// 위 연산 이후 a와 b는 모두 2가 된다.

 

📍 할당 후 결과 예측하기

아래 코드가 실행되고 난 후, a와 x엔 각각 어떤 값이 저장될까?
 

let a = 2;     // 변수 a에는 2 저장

let x = 1 + (a *= 2);     
// a *= 2의 연산이 가장 먼저 수행되면서 변수 a에는 2를 곱한 값인 4 저장
// 1이 더해지면서 변수 x에는 5 저장

 

📍 형 변환

아래 표현식들의 결과를 예측해 보자.
 

"" + 1 + 0     // 1. "10"
"" - 1 + 0     // 2. -1
true + false     // 3. 1
6 / "3"     // 4. 2
"2" * "3"     // 5. 6
4 + 5 + "px"     // 6. "9px"
"$" + 4 + 5     // 7. "$45"
"4px" - 2     // 8. NaN
7 / 0     // 9. Infinity
"  -9  " + 5     // 10. "  -9  5"
"  -9  " - 5     // 11. -14
null + 1     // 12. 1
undefined + 1     // 13. NaN
" \t \n" - 2     // 14. -2

 

하나의 종류의 연산자만 존재할 경우 왼쪽부터 오른쪽으로 순차적으로 계산이 이루어짐을 명심해야 한다.
 
1. 문자열("")과 숫자(1)을 더하면 1이 문자열로 변환되어 "1"이 된다. "1" + 0의 경우도 숫자 0이 문자 "0"으로 변환되어 10이 된다.
2. 더하기를 제외한 수학 연산자들은 숫자형만을 인수로 받는다고 생각하면 된다. 문자열("")과 숫자(1)을 빼려 하면 문자열이 숫자로 변환되어 0 - 1이 되고 (빈 문자열은 숫자로 변환 시 0) 결과는 -1에 0을 더하면 결과는 -1이 된다.
3. true와 false 모두 불리언 형이고 문자열이 피연산자에 없으므로 일반적인 숫자의 덧셈으로 수행된다. true(참)를 숫자로 변환하면 1이고, false(거짓)를 숫자로 변환하면 0이므로 둘을 더한 결과는 1이다.
4. 나누기에서는 숫자형만을 인수로 받으므로 문자가 숫자로 변환되어 나누어지므로 6 / 3 = 2이다.
5. 곱셈에서도 숫자형만을 인수로 받으므로 문자가 숫자로 변환되어 2 * 3 = 6이다.
6. 숫자끼리의 덧셈이 먼저 이루어져 9가 되고, 숫자와 문자의 덧셈이므로 숫자 9가 "9"로 변환되어 최종적으로 "9px"가 답이 된다.
7. 문자와 숫자의 덧셈이 먼저이므로 "$4"가 되고 여기에 숫자 5를 더하면 "$45"가 된다.
8. 뺄셈에서는 숫자형만을 인수로 받는다. "4px"는 숫자와 문자가 섞여 있어 숫자형으로 변환하면 NaN이 된다. NaN에 어떤 산술 연산을 하더라도 결과는 NaN이다.
9. 어떤 숫자든 0으로 나누면 무한(Infinity)이 된다.
10. 공백도 문자에 해당하므로 연산 결과에 포함된다.
11. "  -9  " 를 숫자로 변환 시 앞뒤 공백 제거 후 변환되므로 -9가 된다.
12. null은 숫자형으로 변환 시 0이 된다. (null은 string이 아님.)
13. undefined는 숫자형으로 변환 시 NaN이 된다. (undefined 역시 string이 아님.)
14. 문자열이 숫자형으로 변환 시 문자열 앞뒤의 공백이 삭제된다. \t와 \n은 공백을 만드는 문자이므로 가시적인 공백과 함께 같이 삭제되므로 결국에는 ""만 남게 된다. ""는 빈 문자열로 숫자로 변환 시 0이므로 0 - 2 = -2이다.
 
형 변환에 대한 정보는 다음 게시물을 참고하자.
[Javascript] 형 변환 (tistory.com)

[Javascript] 형 변환

📌 참고 사이트 형 변환 (javascript.info) 형 변환 ko.javascript.info 📋 형 변환 함수와 연산자에 전달되는 값이 적절한 자료형으로 자동 변환되는 것을 형 변환이라고 한다. 예를 들면, alert의 경우 전

developingdiaryoflily.tistory.com

 

📍 덧셈 고치기

아래 코드는 사용자에게 숫자 2개를 입력받은 후 그 합을 보여준다.
그런데 의도한 대로 예시가 동작하지 않는다. 프롬프트 창에 세팅한 기본값을 수정하지 않은 경우 덧셈의 결과는 12가 된다.
왜 그럴까? 예시가 제대로 동작하도록 코드를 수정해 보자. 결과는 3이 되어야 한다.
 

let a = prompt("덧셈할 첫 번째 숫자를 입력해주세요.", 1);
let b = prompt("덧셈할 두 번째 숫자를 입력해주세요.", 2);

alert(a + b);     // 12

 

🅰️
12가 되었다는 것은 1또는 2가 문자열인 상태에서 더하기 연산이 이루어졌다는 의미이다.
prompt 함수는 기재한 값 (값을 따로 수정하지 않을 경우 초깃값 그대로)을 문자열의 형태로 반환한다고 배웠다.
[Javascript] alert, prompt, confirm을 이용한 상호작용 (tistory.com)

[Javascript] alert, prompt, confirm을 이용한 상호작용

📌 참고 사이트 alert, prompt, confirm을 이용한 상호작용 (javascript.info) alert, prompt, confirm을 이용한 상호작용 ko.javascript.info 📋 alert ➡️ alert 함수가 실행되면 사용자가 확인(ok) 버튼을 누를 때까지

developingdiaryoflily.tistory.com

따라서 a와 b에는 각각 문자형의 1과 문자형의 2가 할당되게 된다.
 
결과가 3이 되도록 하려면 a와 b에 저장된 값이 모두 숫자형이어야 한다.
그러므로 a와 b의 앞에 단항 덧셈 연산자 (+) 를 붙여 값을 숫자로 만들어 줄 것이다.
단항 덧셈 연산자는 피연산자가 숫자가 아닌 다른 자료형일 경우 숫자로 바꾸어 준다고 하였다.
(prompt 함수에 적용하는 것도 가능하고, Number 함수를 적용하여 숫자로 변환시켜 주는 것도 가능하다.)
 

let a = prompt("덧셈할 첫 번째 숫자를 입력해주세요.", 1);
let b = prompt("덧셈할 두 번째 숫자를 입력해주세요.", 2);

alert(+a + +b);     // 3

댓글