JavaScript의 Math 객체는 이 언어의 조용한 유틸리티 벨트와 같습니다. 인스턴스화할 필요도 없고, 임포트할 필요도 없습니다. 그저 모든 런타임에 존재하며, 픽셀 값을 반올림하는 것부터 무작위 주사위 값을 생성하는 것까지 모든 것을 처리할 준비가 되어 있습니다. Math는 정적 객체이므로, 모든 메서드와 프로퍼티는 네임스페이스에 직접 연결되어 있습니다. new Math().PI가 아니라 Math.PI라고 작성합니다. 이러한 설계 방식은 단순함을 유지해주지만, 프로덕션 로직에서 이를 신뢰하기 전에 반드시 이해해야 할 까다로운 부분들도 존재함을 의미합니다.
생성자가 없는 정적 객체
대부분의 내장 JavaScript 객체는 인스턴스 생성을 요구합니다. new Date()나 new Array()를 호출하는 식이죠. 하지만 Math는 이를 거부합니다. Math는 원시 Number 타입에서 작동하는 관련 함수와 상수의 네임스페이스로 설계되었습니다. Math.sqrt(16)을 호출하면 4를 얻습니다. new 키워드를 사용하려고 하면 엔진은 TypeError를 발생시킵니다. 이러한 패턴은 메모리를 깨끗하게 유지하며, Math가 순수하게 함수적(functional)임을 나타냅니다. 입력을 받아 출력을 반환할 뿐, 아무것도 변경(mutate)하지 않습니다.
한 가지 꼭 기억해야 할 엄격한 제한 사항이 있습니다. Math는 표준 IEEE 754 숫자로 작동하며, BigInt와는 함께 작동하지 않습니다. Math.round()나 Math.abs()에 BigInt를 전달하면 TypeError가 발생합니다. 애플리케이션이 64비트 정수 또는 그 이상의 크기를 다룬다면, 값을 변환하거나 대신 네이티브 BigInt 연산자를 사용하여 산술 연산을 처리해야 합니다.
실제로 자주 사용하는 상수들
Math 객체는 매직 넘버를 하드코딩하는 수고를 덜어주는 여러 숫자 상수를 제공합니다.
Math.PI는 친숙한 3.14159...로, 원, 삼각법 또는 도(degrees)를 라디안(radians)으로 변환하는 작업에 필수적입니다.Math.E는 오일러 수로, 약 2.718입니다. 지수 성장 곡선, 복리 계산, 로그 스케일 등에서 나타납니다.Math.SQRT2는 2의 제곱근으로, 약 1.414입니다. 정사각형의 대각선이 필요하거나 단순 기하학에서 벡터를 정규화할 때 유용합니다.Math.LN2는 2의 자연로그로, 약 0.693입니다. 이진 트리, 정보 엔트로피 또는 로그-밑-2(log-base-2) 수학을 포함하는 시간 복잡도 분석 알고리즘에서 볼 수 있습니다.
이 값들은 완전한 배정밀도(double-precision) 부동 소수점입니다. 메서드가 아닌 프로퍼티이므로 괄호 없이 접근합니다.
반올림, 부호, 그리고 절대값
가장 일반적인 Math 작업은 숫자를 정리하는 것입니다. JavaScript는 네 가지 반올림 메서드를 제공하는데, 이들은 동작 방식이 서로 다르며, 특히 양수 범위를 벗어날 때 더욱 그렇습니다.
Math.abs(x)는 숫자의 크기(magnitude)를 반환합니다. -42를 전달하면 42를 얻습니다. 방향보다는 거리가 중요할 때 유용합니다. 타임스탬프 비교, UI에서의 드래그 델타(drag delta) 계산, 또는 추측값이 오차 범위 내에 있는지 확인하는 상황을 생각해 보세요.
Math.round(x)는 우리가 흔히 아는 반올림 방식입니다. 가장 가까운 정수를 취하며, 소수점 0.5는 다음 양의 정수로 올림합니다. 따라서 4.4는 4가 되고, 4.5는 5가 됩니다.
Math.ceil(x)는 항상 다음 정수로 올림합니다. 4.1은 5가 되고, -4.9는 -4가 됩니다. 마지막 사례는 사람들을 놀라게 하곤 합니다. 수직선 상에서 -4가 -4.9보다 크기 때문에, 올림(ceiling)은 음수의 경우 0을 향해 이동합니다.
Math.floor(x)는 그 반대입니다. 항상 내림합니다. 4.9는 4가 되고, -4.1은 -5가 됩니다. 검색 결과의 페이지를 매기거나 고정 크기의 메모리 블록을 할당할 때는 보통 floor를 사용합니다.
Math.trunc(x)는 소수점 이하를 완전히 제거하여 정수 부분만 남깁니다. 결과적으로 부호와 상관없이 0을 향해 이동합니다. 4.9는 4가 되고, -4.9는 -4가 됩니다. 부동 소수점을 정수로 캐스팅할 때 소수점을 버리는 언어의 로직을 이식하고 있다면 이 메서드가 유용할 것입니다.
마지막으로, Math.sign(x)는 값이 0의 어느 쪽에 위치하는지 알려줍니다. 양수에는 1, 음수에는 -1, 양의 0에는 0, 음의 0에는 -0을 반환하며, 숫자가 아닌 경우에는 NaN을 반환합니다. if-else 체인을 작성하지 않고도 방향에 따라 분기할 수 있는 간결한 방법입니다.
난수 생성하기
Math.random()은 0(포함)에서 1(미포함) 사이의 의사 난수(pseudo-random) 부동 소수점을 생성합니다. 이는 암호학적으로 안전하지 않으므로, 비밀번호 생성, 토큰 생성 또는 실제 돈과 관련된 작업에는 사용하지 마십시오.
