Menu

자바 Math 클래스: pow, sqrt, abs, round, random 등

자바 Math 클래스 사용법: Math.pow, Math.sqrt, Math.abs, Math.max와 Math.min, round, floor, ceil로 반올림하기, Math.random으로 범위 안의 난수 만들기, 상수 PI와 E, 그리고 각 메서드의 반환 타입.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

정적 메서드 도구 상자

java.lang.Math는 미리 만들어진 수학 함수로 가득한 클래스입니다: 거듭제곱, 제곱근, 절댓값, 반올림, 삼각함수, 로그, 난수. 쓰기 쉬운 이유는 두 가지입니다:

  • 모든 자바 파일이 자동으로 import하는 java.lang에 있습니다. import 줄을 쓸 필요가 없습니다.
  • 모든 메서드가 static입니다. Math.sqrt(25)처럼 클래스 이름으로 호출하고, Math 객체는 절대 만들지 않습니다. static이 무슨 뜻인지는 정적 멤버 페이지에서 설명합니다.

어떤 결과는 .0이 붙어서 출력되고 어떤 결과는 그렇지 않다는 점에 주목하세요. Math의 각 메서드에는 정해진 반환 타입이 있고, 그것을 아는 것이 이 클래스에 대해 배울 내용의 대부분입니다.

메서드하는 일반환 타입
Math.pow(a, b)a의 b 제곱double
Math.sqrt(x)제곱근double
Math.cbrt(x)세제곱근double
Math.abs(x)절댓값x와 같은 타입
Math.max(a, b) / Math.min(a, b)둘 중 큰 값 / 작은 값두 타입 중 더 넓은 타입
Math.round(x)가장 가까운 정수double이면 long, float이면 int
Math.floor(x) / Math.ceil(x)내림 / 올림double
Math.random()0.0 이상 1.0 미만의 난수double
Math.PI, Math.E상수 π와 edouble

Math.pow: 거듭제곱

Math.pow(base, exponent)는 수를 거듭제곱합니다. double 매개변수 두 개를 받고, 정수를 넘겨도 double을 반환합니다:

결과를 int에 저장하려면 (int)로 캐스팅하세요. 작은 정수 거듭제곱에서는 double 결과가 정확하므로 캐스팅해도 올바른 답이 나옵니다. 캐스팅이 잘못되는 것은 결과가 클 때입니다. Integer.MAX_VALUE(2,147,483,647)보다 큰 double은 캐스팅하면 정확히 Integer.MAX_VALUE가 되므로, (int) Math.pow(2, 40)2147483647이 됩니다. 더 큰 거듭제곱은 long으로 캐스팅하고, 2⁵³을 넘으면 double이 모든 정수를 정확히 표현하지 못한다는 점을 기억하세요. 캐스팅이 값에 무엇을 하는지는 타입 캐스팅 페이지에서 다룹니다.

자바에는 거듭제곱 연산자가 없습니다. 2 ^ 3은 컴파일되지만 ^는 비트 XOR이라서 결과는 8이 아니라 1입니다. 자바 수학 코드에서 초보자가 가장 흔히 만드는 버그 중 하나입니다.

천만 이상의 double은 과학적 표기법으로 출력되기 때문에, 10의 거듭제곱을 처음 출력해 보면 놀라게 됩니다:

1.0E7은 1.0 × 10⁷이라는 뜻입니다. 값은 같고 출력되는 형태만 달라집니다. 평범한 숫자로 출력하려면 long으로 캐스팅하거나 String.format("%.0f", value)로 포맷하세요.

Math.sqrt와 Math.cbrt: 제곱근과 세제곱근

Math.sqrt(x)x의 제곱근을 double로 반환합니다. Math.cbrt(x)는 세제곱근을 반환합니다.

음수의 제곱근은 실수가 아니므로 Math.sqrt(-4)는 예외를 던지는 대신 NaN("not a number", 숫자가 아님)을 반환합니다. NaN은 닿는 모든 연산으로 퍼져 나가므로, 음수가 들어올 수 있다면 제곱근을 구하기 전에 입력을 확인하세요. Math.hypot(a, b)sqrt(a*a + b*b)를 직접 계산하며, 두 점 사이의 거리를 구할 때 흔히 씁니다.

Math.abs: 절댓값

Math.abs(x)는 부호를 없앱니다. pow, sqrt와 달리 넘겨준 것과 같은 타입을 반환합니다. int에는 int를, double에는 double을 반환합니다.

두 위치 사이의 거리처럼, 방향이 아니라 크기만 중요한 차이를 구할 때 주로 씁니다.

Math.max와 Math.min

Math.max(a, b)는 두 값 중 큰 값을, Math.min(a, b)는 작은 값을 반환합니다. 인자는 정확히 두 개를 받습니다. 세 개 이상이면 호출을 중첩하세요:

두 인자의 타입이 다르면 좁은 쪽이 먼저 넓어집니다. Math.max(3, 7.5)double 값 두 개를 비교하고 double을 반환합니다. 마지막 예제는 값을 0에서 100 사이로 제한합니다. Math.min이 100을 상한으로 두고, Math.max가 0 아래로 내려가지 않게 막습니다.

반올림: round, floor, ceil

자바에는 반올림 메서드가 세 개 있고, 방향과 반환 타입이 모두 다릅니다:

  • Math.round는 가장 가까운 정수로 갑니다. 정확히 중간인 값은 양의 무한대 쪽으로 올라가므로 2.53, -2.5-2가 됩니다. double 인자에는 long을 반환합니다(float에는 int).
  • Math.floor는 항상 음의 무한대 쪽으로 내리고, double을 반환합니다.
  • Math.ceil은 항상 양의 무한대 쪽으로 올리고, double을 반환합니다.
  • (int) 캐스팅은 반올림이 전혀 아닙니다. 소수 부분을 버리기 때문에 양수는 아래로, 음수는 위로 움직입니다.

Math.round(double)long을 반환하므로 캐스팅 없이 int에 대입하면 컴파일되지 않습니다:

int n = Math.round(2.6);          // error: incompatible types: possible lossy conversion from long to int
int m = (int) Math.round(2.6);    // OK, m은 3
long k = Math.round(2.6);         // OK

소수 몇째 자리까지 반올림하려면 크게 만들고, 반올림하고, 다시 줄이세요. 100이 아니라 100.0(double)으로 나눠야 소수 부분이 남습니다:

두 번째 줄은 longint로 나누는 정수 나눗셈이라서 소수 부분이 사라집니다. 반올림한 숫자를 보여주기만 하면 된다면 String.format("%.2f", value)가 더 간단하고, 저장된 값도 바꾸지 않습니다.

Math.random: 난수

Math.random()0.0 이상 1.0 미만의 double을 반환합니다. 호출할 때마다 값이 다르므로, 이 섹션의 프로그램은 Run을 누를 때마다 출력이 바뀝니다.

범위 안의 정수를 얻으려면 그 값을 늘리고, 캐스팅하고, 옮기면 됩니다. min부터 max까지(둘 다 포함)의 정수는 이렇게 구합니다:

int value = (int) (Math.random() * (max - min + 1)) + min;

min이 1이고 max가 6인 주사위로 동작 방식을 보면 다음과 같습니다:

  1. Math.random() * 60.0 이상 6.0 미만의 double을 줍니다.
  2. (int)가 소수 부분을 버려서 0, 1, 2, 3, 4, 5 중 하나가 됩니다.
  3. + 1이 그 값을 1, 2, 3, 4, 5, 6으로 옮깁니다.

첫 줄은 무작위로 굴린 주사위 다섯 번을 보여줍니다. 둘째 줄은 만 번 굴린 결과를 확인하는데, 실제로는 항상 lowest: 1, highest: 6을 출력합니다. 이 공식은 범위의 양 끝에 모두 닿고, 그 밖으로는 절대 나가지 않습니다.

Math.random() * (max - min + 1)을 감싼 괄호가 중요합니다. 캐스팅은 바로 뒤의 값에 적용되므로, (int) Math.random() * 6Math.random()을 먼저 캐스팅합니다. 그 값은 항상 0이고 0 * 60이라서, 모든 "주사위"가 같은 값으로 나옵니다.

Math.random()은 게임과 연습 문제에는 충분합니다. 그 이상이 필요하면 java.util.Random 클래스와 ThreadLocalRandom.current().nextInt(min, max + 1)(java.util.concurrent에 있음)이 정수를 바로 반환하고, Random은 시드를 받아 테스트에서 같은 순서를 반복할 수 있습니다. 이 중 어느 것도 비밀번호나 보안 토큰에는 적합하지 않습니다. 그런 용도에는 java.security.SecureRandom을 쓰세요.

Math.PI와 Math.E

Math.PI(π)와 Math.E(오일러 수 e)는 static final double 상수입니다:

3.14를 직접 입력하는 대신 이 상수를 쓰세요. double이 허용하는 한 가장 정확하고, 이름만 봐도 무슨 숫자인지 알 수 있습니다.

정수 결과와 double 결과

Math 메서드 대부분은 double을 받고 double을 반환합니다. int 값을 넘기면 자바가 인자를 자동으로 double로 넓혀 주지만, 호출 전에 작성한 연산은 여전히 int로 계산됩니다. 틀린 답은 대부분 여기서 나옵니다:

items / perBox7 / 2이고, int 두 개를 나누면 나머지가 버려지므로 Math.ceil이 보기도 전에 3이 됩니다. Math.ceil(3.0)3.0입니다. 캐스팅이나 4.0 같은 리터럴로 피연산자 하나를 double로 만들어야 나눗셈이 소수 부분을 유지합니다. 정수 나눗셈은 연산자 페이지에서 더 자세히 설명합니다.

일반적인 규칙은 이렇습니다. 최종적으로 원하는 타입을 정하고, 소수 부분이 중요하면 나눗셈이나 곱셈이 double로 계산되게 하고, intlong으로의 캐스팅은 마지막에 한 번만 하세요.

그 밖의 유용한 메서드

같은 클래스의 메서드 몇 가지를 더 보겠습니다. 모두 같은 방식으로 호출합니다:

  • Math.log는 자연로그이고, Math.log10은 밑이 10인 로그입니다.
  • Math.floorMod(a, b)b의 부호를 따르는 나머지를 줍니다. 요일처럼 범위를 한 바퀴 도는 계산에 필요한 것이 바로 이것입니다. % 연산자는 a의 부호를 유지합니다.
  • 삼각함수 메서드(sin, cos, tan)는 라디안을 받습니다. 도 단위는 먼저 Math.toRadians로 변환하세요.
  • Math.addExact, Math.multiplyExact와 그 형제 메서드들은 오버플로가 나면 조용히 음수로 넘어가는 대신 ArithmeticException을 던집니다.

자주 묻는 질문

자바에서 Math.pow는 어떻게 쓰나요?

Math.pow(base, exponent)baseexponent만큼 거듭제곱한 값을 double로 반환하므로, Math.pow(2, 3)8.0입니다. 결과를 int에 저장하려면 캐스팅하세요: int n = (int) Math.pow(2, 10);1024가 됩니다. 자바에는 거듭제곱 연산자 ^가 없습니다. ^는 비트 XOR입니다.

Math.random으로 범위 안의 난수를 만들려면 어떻게 하나요?

Math.random()0.0 이상 1.0 미만의 double을 반환합니다. min부터 max까지(양 끝 포함)의 정수를 얻으려면 (int) (Math.random() * (max - min + 1)) + min을 쓰세요. 주사위 굴리기는 (int) (Math.random() * 6) + 1입니다.

자바에서 Math 클래스를 import해야 하나요?

아니요. Math는 모든 자바 파일이 자동으로 import하는 java.lang 패키지에 있습니다. 메서드가 모두 static이라서 객체를 만들지 않고 Math.sqrt(16)처럼 클래스 이름으로 호출합니다.

자바에서 Math.round는 왜 long을 반환하나요?

doubleint보다 훨씬 큰 값을 담을 수 있기 때문에 Math.round(double)long을 반환합니다. 결과를 int에 대입하려면 캐스팅이 필요합니다: int n = (int) Math.round(2.6);. Math.round(float)int를 반환합니다.

Math.floor, Math.ceil, Math.round의 차이는 무엇인가요?

Math.floor는 내림(2.72.0, -2.3-3.0), Math.ceil은 올림(2.13.0), Math.round는 가장 가까운 정수로 가고 딱 절반이면 올립니다(2.53). floorceildouble을 반환하고, roundlong을 반환합니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기