게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌10 - JavaScript - 8년 전 등록

숫자와 Math 객체

안녕하세요 이번 시간에는 숫자(Number)에 대해 알아보겠습니다. 숫자도 원시 래퍼 객체(new Number())가 있습니다. 그래서 메소드를 가질 수 있습니다. 사실 숫자만으로는 양이 별로 없어서 Math 객체까지 같이 알려드리겠습니다.

숫자

간단한 문제를 풀어봅시다.

var a = 0.1;
var b = 0.2;
a + b; // 뭘까요?

장난하냐고요? 0.3이라고요? 똑똑한 컴퓨터한테 물어봅시다. 컴퓨터는 계산을 틀리지 않으니까요.

a + b; // 0.30000000000000004

네 그렇습니다. 지금까지 인간은 간단한 덧셈조차 못하고 있던겁니다...가 아니라 인간이 계산 중에 유일하게 컴퓨터를 이길 수 있는 분야입니다. 몇몇 프로그래밍 언어들은 소수점을 계산하지 못하는 치명적인 단점을 가지고 있습니다. 대충 이유는 다음과 같습니다. 컴퓨터는 소수를 2진법으로 바꿔서 계산하는데 2진법으로 바꾸면 몇몇 소수(위와 같은 경우)는 무한소수가 됩니다. 저장공간이 정해져있는 컴퓨터는 무한소수의 값을 다 저장하지 못하고 끝부분을 버려 유한소수로 만듭니다. 그 버린 부분 때문에 오차가 발생합니다. 말은 장황해도 뭐 어쨌든 계산을 못한다는 거죠. 그래서 이를 극복하기 위해 다음과 같은 방법을 쓰기도 했습니다.

(10 * a + 10 * b) / 10; // 0.3

a와 b에 10을 곱해 정수로 만든 후 계산한 뒤, 마지막에 10으로 다시 나눠주는 거죠. 번거로운 과정입니다. 하지만 자바스크립트에는 위와 같은 과정을 거치지 않게 해 줄 메소드들이 있습니다.

숫자.toFixed(소수자릿수), 숫자.toPrecision(자릿수)

(a + b).toFixed(2); // '0.30'
0.00125.toPrecision(2); // '0.0013'
1.2356.toFixed(3); // '1.236'
1.2346.toPrecision(2); // '1.2'

toFixed 함수는 지정된 소수자릿수까지 반올림해서 나타냅니다. 문자열로 반환하기 때문에 숫자로 바꿔주는 작업이 필요합니다. 소수점 연산을 정확하게 만들려면 자릿수를 지정해줘야합니다.

toPrecision은 지정된 자릿수만큼만 표현해 문자열로 반환합니다. 만약 소수일 경우 앞의 0들은 무시합니다. 0.00125.toPrecision(2)은 두 자릿수까지만 표현해야 하는데, 소수이기 때문에 0.0이 아니라 0.0013이 됩니다. 앞의 0들을 다 무시했기 때문에 남은 125에서 반올림 후 두 자릿수를 자른 겁니다.

isNaN(숫자)

3 / "가"; // NaN
isNaN(3/"가"); // true

안에 넣은 숫자가 진짜 숫자인지 테스트합니다. true/false로 알려줍니다. NaN이라는 값이 처음 나왔는데요. NaN이란 Not a Number로 '3 나누기 "가"' 처럼 숫자가 아닌 계산을 하면 NaN 값이 나옵니다. NaN도 하나의 숫자값입니다. isNaN은 숫자가 아닌 값들에 대해 true를 알려줍니다. 하지만 isNaN은 지금 현재 문제가 있는 함수라고 소문나 있습니다.

NaN의 특별한 성질 중 하나는 자바스크립트에서 유일하게 자기 자신과 같지 않은 값이라는 겁니다.

NaN == NaN; // false

재밌는 놈입니다. 위에 isNaN 함수보다 이 방법을 사용하는 게 더 판별에 효과적입니다.

Infinity

내친김에 숫자값 하나 더 알아보고 가죠.

3 / 0; // Infinity
-3 / 0; // -Infinity

0으로 나누었을 경우 Infinity 값이 나옵니다. 말 그대로 무한입니다. 그리고 음의 무한일 경우에는 -Infinity가 됩니다.

parseInt(숫자, 진법), parseFloat(숫자)

parseInt("1등", 10); // 1
parseFloat("0.5달러"); // 0.5
parseFloat(0.3.toFixed(2)); // 0.3

자주 쓰일 두 종류는 외워두는 게 좋습니다. parseInt는 정수로, parseFloat는 실수로 바꿔줍니다. 아까 toFixed와 toPrecision은 모두 문자열을 반환하는데, 이 값을 다시 숫자로 만드려면 parseInt, parseFloat을 해줘야합니다. 참고로 문자열이더라도 숫자로 시작하면 뒤에 글자들은 없애고 숫자로 바꿔줍니다. 숫자로 시작하지 않으면 NaN이 됩니다.

Number(아무거나)

Number("1"); // 1
Number("0.5달러"); // NaN

Number객체 자체가 함수로 쓰일 수 있습니다(위에서 말한 원시 래퍼 객체와는 조금 다릅니다). 객체가 어떻게 함수로 쓰이는지는객체 지향 프로그래밍을 할 때 알려드리겠습니다. parseInt, parseFloat과 다른점은 문자열에 문자가 들어있으면 처리하지 못하고 NaN이 됩니다.

숫자는 2진법, 8진법, 16진법을 표시할 수 있습니다. 2진법은 숫자 앞에 0b를, 8진법은 0을, 16진법은 0x를 붙이면 됩니다.

0b111; // 7
017; // 15
0xA3; // 163

이제 Math 객체에 대해 알아보겠습니다. 

Math

각종 수학 계산을 도와줍니다. 이 객체는 Number과는 달리 Math()처럼 함수로는 사용할 수 없습니다.

Math.random()

예전에 보셨죠? 0부터 1 사이의 랜덤 값을 뽑아줍니다. 1은 불포함입니다.

Math.random(); // 0.xxxxxxxxx 매번 할 때마다 달라짐

Math.floor(값), Math.ceil(값), Math.round(값)

각각 숫자를 정수값으로 내림, 올림, 반올림합니다. 소수점을 반올림하려면 toFixed를 써야합니다.

Math.floor(5.5); // 5
Math.ceil(5.5); // 6
Math.round(5.5); // 6
Math.round(5.49); // 5

Math.abs(값)

절대값을 알려줍니다.

Math.abs(-15); // 15

Math.pow(값, 지수), Math.sqrt(값)

Math.pow는 거듭제곱이고, sqrt는 제곱근입니다.

Math.pow(2, 3); // 8
Math.sqrt(16); // 4

Math.max(값, 값, ...), Math.min(값, 값, ...)

Math.max(5, 6, 10); // 10
Math.min(2, 8, 9); // 2

여러 값들 중에 최대, 최소값을 찾아줍니다.

Math.PI

여러분을 학교 다닐 때 괴롭혔던 파이(π)입니다.

이외에도 Math 객체는 싸인, 코싸인, 탄젠트를 표시하는 것과 지수함수, 로그함수 등등 많은 것을 지원합니다. 저는 아직 써본 적은 없지만 3D 그래픽 작업, 게임 프로그래밍이나 물리학 관련 일을 하실 거면 필요하겠네요.

다음 시간은 배열에 대해서 알아보겠습니다.

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

6개의 댓글이 있습니다.
4년 전
초보자도 알기쉽고 자세하게 설명해주셔서 감사합니다
6년 전
isNan 설명에 '재밌는 놈입니다. 위에 isNaN 함수보다 이 방법을 사용하는 게 더 판별에 효과적입니다.' 혹시 반대로 적으신건가요..? 이해가 잘 안됩니다 ㅜㅜ
6년 전
NaN == NaN 으로 판단하는게 값이 NaN인지 찾는 가장 좋은 방법입니다. ES2015에서는 Number.isNaN 메서드가 생겼습니다.
5년 전
본문내용에 언급하셨던 NaN === NaN; // false인데 Number.isNaN(NaN); // true 네요. 좋은 정보 배워갑니다 :)
7년 전
parseInt("1등", 10); // 1
이게 parseInt() 안에 있는 "1등", 10 이 어떤 알고리즘으로 1만 반환하는지 알려주실수 있나요?
"문자열이더라도 숫자로 시작하면 뒤에 글자들은 없애고 숫자로 바꿔줍니다." 라는 설명으로
"1등"에서 1만 반환하는건 이해하겠는데 ,뒤에있는 10은 왜 반환하지 않나요?
7년 전
뒤의 10은 변환 대상이 아니라 십진수로 변환하라는 것을 나타냅니다!
7년 전
아 감사합니다! 그럼 혹시 10진수이외의 다른 진수로도 변환이 가능한가요?
7년 전
네 한 번 다른 숫자를 넣어서 해보세요!
8년 전
예제 중에 0.00125.toPrecision(2); // '0.0012' 이 아닌 '0.0013'을 반환하던데 얘도 반올림해서 반환하는 녀석인가요?
8년 전
아 맞아요. 수정하겠습니다!
8년 전
그isNaN을 제외하고 NaN값인지 아닌지 판단하는 방법이 제 수준에선 자세하게 설명되지 않은거 같아요ㅜ
8년 전
아 ES2015 강좌 14에서 Number로 바뀌면서 안전해졌다고 언급되어있네요!
8년 전
toPrecision 에서 0.00125.toPrecision(2)은 0.0이 아니라 0.0012입니다. 앞의 0들이 다 무시되었기 때문이죠. 이부분이 잘 이해가 안갑니다 ㅠㅠ
8년 전
Precision(2)는 주어진 숫자 갯수만큼 정확하게 나타내라는 뜻입니다. 그래서 2가 주어졌으면 두개만큼 정확하게 나타내는 건데 소수일경우는 앞의 0들은 무시하고 뒤의125 중에서 두 개 만큼만 정확하게 표현한 겁니다