웹/JavaScript
[Javascript] 숫자형, 부동소수점, 실수 계산 오차, boolean, isNaN, ??,연산자 우선순위
Judith Hopps
2023. 1. 9. 21:29
반응형
I. 숫자 자료형으로 표현되는 것
1. 양과 음의 정수와 실수
// 자바스크립트에는 정수와 실수의 자료형이 따로 있지 않음
정수와 소수, 음수 모두 number!
let integer = 100;
let real = 1.234;
let negative = -5.67;
console.log(
typeof integer,
typeof real,
typeof negative
);
2. 무한대
let x = 1 / 0;
console.log(x, typeof x);
// 무한대에는 양음이 있음
console.log(-x, typeof -x);
let y = -1 / 0;
console.log(y, typeof y);
let z = Infinity;
console.log(z, typeof z);
3. 숫자가 아닌 것 Not a Number
let x = 1 / 'abc';
let y = 2 * '가나다';
let z = NaN;
console.log(x, typeof x);
console.log(y, typeof y);
console.log(z, typeof z);
// NaN은 양음이 없음
console.log(-NaN);
⭐️ 주어진 값이 NaN인지 여부 확인하는 방법
let x = 1 / 'abc';
console.log(
x,
x == NaN,
x === NaN,
isNaN(x), // 숫자가 아닐 시 true
Number.isNaN(x) // 보다 엄격한 버전
);
isNaN과 Number.isNaN의 차이
console.log(
typeof '1', isNaN('1'), Number.isNaN('1')
); // 특정 숫자로 변환 가능한 문자
console.log(
typeof true, isNaN(true), Number.isNaN(true)
); // true는 1, false는 0으로 변환됨
console.log(
typeof 'a', isNaN('a'), Number.isNaN('a')
); // ⚠️ 특정 숫자로 변환 불가인 문자의 경우 차이
console.log(
typeof (1/'a'), isNaN(1/'a'), Number.isNaN(1/'a')
); // NaN값인 경우
간단정리
기능 ( 메서드 )설명
isNaN | 숫자가 아니다 싶으면 무조건 true 반환 |
Number.isNaN | 숫자 자료형인 주제에 숫자가 아니어야만 true 반환 |
II. 연산자
1. 산술 연산자
a. 이항 산술 연산자
- +, -, *, /, %, **
- 셈의 결과를 반환
- 부수효과 없음
// 값 반환
let x = 10;
let y = x * 10;
console.log(y);
console.log(
y + 1, // 덧샘
y - 1, // 뺄셈
y * 2, // 곱셈
y / 5, // 나눗셈
y % 3, // 나머지
y ** 2 // 제곱
);
// 부수효과 없음
console.log(y);
// 널리 사용되는 홀수와 짝수의 판별법
console.log(
'홀수 ',
123 % 2,
55 % 2,
999 % 2
);
console.log(
'짝수 ',
2 % 2,
100 % 2,
8 % 2
);
💡 괄호의 사용
console.log(
4 * 1 + 2,
4 * (1 + 2),
4 * -(1 + 2),
-(4 * -(1 + 2))
);
b. 단항 산술 연산자
연산자반환부수효과
a++ | 값 그대로 | 1 증가 |
++a | 1 증가한 값 | 1 증가 |
a-- | 값 그대로 | 1 감소 |
--a | 1 감소한 값 | 1 감소 |
+a | 값 그대로 | 없음 |
-a | 양음을 반전한 값 | 없음 |
let x = 10;
// 값을 반환부터 하고 증가
console.log('1.', x++, x);
// 값을 증가부터 하고 반환
console.log('2.', ++x, x);
let x = 3;
let y = 4;
// 💡 부수효과가 일어나는 시점
console.log(x-- * --y, x, y);
let x = 1;
console.log(
+x,
-x,
-(-x),
-(x++),
-x * -1
);
💡 문자열을 숫자로 바꿈
console.log(
+'100',
-'100',
+'abc' // 숫자로 변환될 수 없는 문자열
);
let x = '100';
console.log(x++, x);
let y = '100';
console.log(--y, y);
// 숫자로 변환될 수 없는 문자열
// 첫 번째 값 주의 - 증가 이전에도 변환
let z = 'abc';
console.log(z++, z);
2. 할당 산술 연산자 부수효과
연산자의미
x += y | x = x + y |
x -= y | x = x - y |
x *= y | x = x * y |
x /= y | x = x / y |
x %= y | x = x % y |
x **= y | x = x ** y |
let x = 3;
x += 2;
console.log(x);
x -= 3;
console.log(x);
x *= 12;
console.log(x);
x /= 3;
console.log(x);
x %= 5;
console.log(x);
x **= 4;
console.log(x)
let y = 25;
console.log(
y **= 0.5, // 할당된 결과 반환
y
);
💡 자바스크립트의 number 자료형은 부동소수점 사용
- IEEE 754 표준 double 형식 (64비트)
- 자바스크립트에는 기본 정수 자료형이 없음
- BigInt (내장 객체) - 이후 배울 것
Q. 0.1+0.2 === 0.3이 false인 이유??
a. 숫자를 2진수로 변환해서 값을 계산하기 때문
console.log(
0.1 + 0.2,
0.1 + 0.2 === 0.3 // false
);
let x = 0.1 * 10;
let y = 0.1 + 0.1 + 0.1 + 0.1 + 0.1
+ 0.1 + 0.1 + 0.1 + 0.1 + 0.1;
console.log(
x, y, x === y
);
console.log(
0.2 * 0.7,
0.4 * 3,
0.9 - 0.6,
0.9 - 0.3
);
// ⭐️ 2의 거듭제곱으로 나눈 수의 계산은 정확
console.log(
0.25 * 0.5,
0.5 + 0.25 + 0.125 + 0.125,
0.0625 / 0.25
);
🧮 정확한 계산이 필요할 때는? - 라이브러리 활용
- 이후 모듈 관련 강에서 배울 것
. 연산자
1. 부정 연산자
console.log(
true, !true, false, !false
);
console.log(
true, !true, !!true, !!!true
);
console.log(
false, !false, !!false, !!!false
);
console.log(
true === !false,
!(1 == '1'),
!(1 === '1'),
!(typeof false === 'boolean')
);
2. AND / OR 연산자
a. && - AND : 양쪽 모두 true 여부 반환
console.log(
true && true,
true && false,
false && true,
false && false,
);
b. || - OR : 한 쪽이라도 true 여부 반환
console.log(
true || true,
true || false,
false || true,
false || false,
);
let x = 14;
// x = 6;
// x = 25;
console.log(
(x > 10 && x <= 20) || x % 3 === 0
);
// 💡 드 모르간의 법칙
let a = true;
// a = false;
let b = true;
// b = false;
console.log(
!(a && b) === (!a || !b),
!(a || b) === (!a && !b)
); // 💡 항상 true
💡 단축평가 short circuit
- && : 앞의 것이 false면 뒤의 것을 평가할 필요 없음
- || : 앞의 것이 true면 뒤의 것을 평가할 필요 없음
- 평가는 곧 실행 - 이 점을 이용한 간결한 코드
- 💡 연산 부하가 적은 코드를 앞에 - 리소스 절약
let error = true;
// error = false;
// 앞의 것이 true일 때만 뒤의 코드 실행
error && console.warn('오류 발생!');
// 앞의 것이 false일 때만 뒤의 코드 실행
error || console.log('이상 없음.');
let x = true;
// x = false;
// ⭐️ &&, || 연산자는 값 자체를 반환
let y = x && 'abc';
let z = x || 123;
console.log(y, z);
3. 삼항연산자 - ~ ? ~ : ~
let x = true;
// x = false;
let y = x ? '참입니다.' : '거짓입니다.';
console.log(y);
let num = 103247;
console.log(
'num은 3의 배수' +
(num % 3 === 0 ? '입니다.' : '가 아닙니다.')
);
let error = true;
//error = false;
error
? console.error('오류 발생!')
: console.log('이상 없음');
II. Truthy vs Falsy
true 또는 false로 평가되는 값들
1. Truthy
console.log(
1.23 ? true : false,
-999 ? true: false,
'0' ? true : false,
' ' ? true : false,
Infinity ? true : false,
-Infinity ? true : false,
{} ? true : false,
[] ? true : false,
);
// ⚠️ true와 `같다`는 의미는 아님
console.log(
1.23 == true,
' ' == true,
{} == true
);
2. Falsy
console.log(
0 ? true : false,
-0 ? true : false,
'' ? true : false,
null ? true : false,
undefined ? true : false,
NaN ? true : false,
);
// 💡 어떤 값들은 false로 타입변환됨
console.log(
0 == false,
0 === false,
'' == false,
'' === false
);
console.log(
null == false,
undefined == false,
NaN == false,
);
let x = 0;
let y = 1;
x && x++;
y && y++;
console.log(x, y);
let x = 2;
let y = 3;
console.log(
x % 2 ? '홀' : '짝',
y % 2 ? '홀' : '짝'
);
let x = '';
let y = '회사원';
let z = x || y;
console.log(z);
x = x || '단기알바';
y = y || '단기알바';
console.log(x, y);
💡 boolean으로 직접변환
// 한 번 부정
console.log(
!1, !-999, !'hello',
!0, !'', !null
);
// ⭐️ 두 번 부정하여 해당 boolean값으로
console.log(
!!1, !!-999, !!'hello',
!!0, !!'', !!null
);
let x = 123;
console.log(
'x는 홀수인가?',
!!(x % 2)
);
I. 기타 연산자들
1. 쉼표 연산자
- 왼쪽부터 차례로 실행, 마지막 것 반환
let x = 1, y = 2, z = 3;
console.log(x, y, z);
// 마지막으로 실행한 것 반환
console.log(
(++x, y += x, z *= y)
);
2. ?? - null 병합 연산자
- ||와 달리, falsy가 아닌 null 또는 undefined만 대체
let x;
x ?? console.warn(x, 'x에 값이 없습니다.');
x = 0;
x ?? console.warn(x, 'x에 값이 없습니다.');
x = null;
x ?? console.warn(x, 'x에 값이 없습니다.');
let a = false;
let b = 0;
let c = '';
let d = null;
let e;
console.log(
a ?? '기본값',
b ?? '기본값',
c ?? '기본값',
d ?? '기본값',
e ?? '기본값',
);
활용예
let baby1 = '홍길동';
let baby2; // 아직 이름을 짓지 못함
const nameTag1 = baby1 ?? '1번 아기';
const nameTag2 = baby2 ?? '2번 아기';
console.log(nameTag1, nameTag2);
병합 할당 연산자들
let x = 0;
let y = '';
let z = null;
x ||= 100;
y &&= '있어야 바뀜';
z ??= '기본값';
console.log(x, y, z);
II. 연산자의 우선순위
💡 우선순위 높은순 현재까지 다룬 연산자들 중
순위연산자들1 | !, +, -, ++, --, typeof |
2 | ** |
3 | *, /, % |
4 | +, - |
5 | <, <=, >, >= |
6 | ==, !=, ===, !== |
7 | && |
8 | || |
9 | =, +=, -=, *=, /=, %=, **=, &&=, ||=, ??= |
10 | , |
👉 전체 연산자 우선순위 (MDN)
let x = 1;
let y = 19 === 3 + 4 * 2 ** ++x;
console.log(y);
console.log(
2 > 3 || 4 % 2 === 0,
2 > (3 || 4) % 2 === 0,
2 > 3 || 4 % (2 === 0)
);
반응형