웹/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. 삼항연산자 - ~ ? ~ : ~

👉 MDN 문서 보기

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)
);
 
반응형