Numbers

이 섹션에서는 java.lang 패키지의 Number 클래스와 그 서브 클래스, 그리고 원시 숫자 타입이 아닌 이러한 클래스의 인스턴스를 사용하는 상황에 대해 설명합니다.

이 섹션에서는 형식이 지정된 숫자 출력을 작성하는 메서드를 제공하는 PrintStreamDecimalFormat 클래스도 소개합니다.

마지막으로, java.langMath 클래스에 대해 설명합니다. 이 클래스에는 언어에 내장된 연산자를 보완하는 수학 함수가 포함되어 있습니다. 이 클래스에는 삼각 함수, 지수 함수 등에 대한 메서드가 있습니다.

숫자로 작업할 때는 대부분 코드에서 기본 타입을 사용합니다. 예를 들어

int i = 500;
float gpa = 3.65f;
byte mask = 0x7f;

그러나 원시값 대신 객체를 사용하는 데에는 여러 가지 이유가 있으며, Java 플랫폼은 각 원시 데이터 타입에 대해 래퍼(Wrapper) 클래스를 제공합니다. 이러한 클래스는 객체에서 프리미티브를 “래핑”합니다. 객체가 예상되는 곳에서 원시값을 사용하는 경우 컴파일러가 해당 원시값을 래퍼 클래스에 넣어 래핑하는 경우가 많습니다. 마찬가지로 원시값이 예상되는 곳에서 숫자 객체를 사용하면 컴파일러가 객체의 박스를 해제합니다. 자세한 내용은 오토박싱 및 언박싱 섹션을 참조하세요.

모든 숫자 래퍼 클래스는 추상 클래스 Number의 서브클래스입니다:

The Number Class Hierarchy

숫자 클래스 계층 구조

참고: 여기서는 설명하지 않는 Number의 다른 네 가지 서브 클래스가 있습니다. BigDecimalBigInteger는 고정밀 계산에 사용됩니다. AtomicIntegerAtomicLong은 멀티스레드 응용 프로그램에 사용됩니다.

원시값 대신 Number 객체를 사용하는 세 가지 이유가 있습니다:

  1. 객체를 기대하는 메서드의 인자로 (숫자 컬렉션을 조작할 때 자주 사용됨).
  2. 데이터 타입의 상한과 하한을 제공하는 MIN_VALUEMAX_VALUE와 같이 클래스에서 정의한 상수를 사용할 경우.
  3. 클래스 메서드를 사용하여 값을 다른 기본 타입으로 변환하고, 문자열로 변환하고, 숫자 체계(10진수, 16진수, 16진수, 이진수) 간에 변환할 수 있습니다.

다음 표에는 Number 클래스의 모든 서브클래스가 구현하는 인스턴스 메서드가 나열되어 있습니다.

다음 메서드는 이 Number 객체의 값을 반환된 원시 데이터 타입으로 변환합니다.

다음 메서드는 이 Number 객체를 인자와 비교합니다.

equals(Object obj) 메서드는 이 숫자 객체가 인자와 같은지 여부를 판단합니다. 인수가 null이 아니고 동일한 타입의 동일한 숫자 값을 가진 객체이면 true를 반환합니다. DoubleFloat 객체에 대한 몇 가지 추가 요구 사항은 Java API 문서에 설명되어 있습니다.

Number 클래스에는 숫자를 문자열로 변환하거나 숫자 체계 간에 변환하는 데 유용한 다른 메서드가 포함되어 있습니다. 다음 표에는 Integer 클래스에 있는 이러한 메서드가 나열되어 있습니다. 다른 Number 서브클래스의 메서드도 비슷합니다:

MethodDescription
static Integer decode(String s)문자열을 정수로 디코딩합니다. 10진수, 8진수 또는 16진수의 문자열 표현을 입력으로 받을 수 있습니다.
static int parseInt(String s)정수를 반환합니다(10진수만 해당).
static int parseInt(String s, int radix)10진수, 이진수, 8진수 또는 16진수(기수는 각각 10, 2, 8 또는 16)의 문자열 표현이 입력으로 주어지면 정수를 반환합니다.
static toString()Interger의 값을 나타내는 String 객체를 반환합니다.
static String toString(int i)지정된 정수를 나타내는 String 객체를 반환합니다.
static Integer valueOf(int i)지정된 원시값을 가진 Integer 객체를 반환합니다.
static Integer valueOf(String s)지정된 문자열 표현의 값을 포함하는 Integer 객체를 반환합니다.
static Integer valueOf(String s, int radix)기수 값으로 구문 분석된 지정된 문자열 표현의 정수 값을 포함하는 Integer 객체를 반환합니다. 예를 들어 s = “333”, 기수 = 8인 경우 이 메서드는 10진수 333에 해당하는 10진수 정수를 반환합니다.

 

숫자 인쇄 출력 포맷 지정하기

앞서 문자열을 표준 출력 System.out으로 인쇄하기 위해 printprintln 메서드를 사용하는 방법을 살펴봤습니다. 모든 숫자를 문자열로 변환할 수 있으므로 이 메서드를 사용하여 문자열과 숫자를 임의로 혼합하여 출력할 수 있습니다. 그러나 Java 프로그래밍 언어에는 숫자가 포함된 경우 인쇄 출력을 훨씬 더 효과적으로 제어할 수 있는 다른 메서드가 있습니다.

Printf와 포맷 메서드

java.io 패키지에는 printprintln을 대체하는 데 사용할 수 있는 두 가지 형식 지정 메서드가 있는 PrintStream 클래스가 포함되어 있습니다. 이 메서드인 formatprintf는 서로 동일합니다. 여러분이 사용하던 익숙한 System.outPrintStream 객체이므로 System.out에서 PrintStream 메서드를 호출할 수 있습니다. 따라서 이전에 print 또는 println을 사용하던 코드의 어느 곳에서나 format 또는 [printf](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/io/PrintStream.html#printf(java.lang.String,java.lang.Object…)]를 사용할 수 있습니다. 예를 들어

System.out.format(.....);

이 두 java.io.PrintStream 메서드의 구문은 동일합니다:

public PrintStream format(String format, Object... args)

여기서 format은 사용할 서식을 지정하는 문자열이고 args는 해당 서식을 사용하여 인쇄할 변수의 목록입니다. 간단한 예는 다음과 같습니다.

System.out.format("The value of " + "the float variable is " +
     "%f, while the value of the " + "integer variable is %d, " +
     "and the string is %s", floatVar, intVar, stringVar); 

첫 번째 매개 변수인 format은 두 번째 매개 변수인 args의 객체의 서식을 지정하는 형식 문자열입니다. format 문자열에는 일반 텍스트와 형식 지정자, 즉 Object... 인수의 형식을 지정하는 특수 문자가 포함되어 있습니다. (Object... args 표기법은 _varargs_라고 불리며, 이는 인자 수가 다를 수 있음을 의미합니다).

형식 지정자는 퍼센트 기호(%)로 시작하고 변환기로 끝납니다. 변환기는 포맷할 인수의 타입을 나타내는 문자입니다. 퍼센트 기호(%)와 변환기 사이에는 선택적 플래그와 지정자를 사용할 수 있습니다. 많은 변환기, 플래그 및 지정자가 있으며, java.util.Formatter에 문서화되어 있습니다.

다음은 기본 예제입니다:

int i = 461012;
System.out.format("The value of i is: %d%n", i)

%d는 단일 변수가 10진수임을 지정합니다. %n은 플랫폼에 독립적인 개행 문자입니다. 출력은 다음과 같습니다:

The value of i is: 461012

printfformat 메서드가 오버로드 되어있습니다. 각각 다음과 같은 구문을 가진 버전이 있습니다:

public PrintStream format(Locale l, String format, Object... args)

예를 들어 부동 소수점 숫자의 영어 표현에서 소수점 이하 자리 대신 쉼표가 사용되는 프랑스어 시스템으로 숫자를 인쇄하려면 다음과 같이 사용합니다:

System.out.format(Locale.FRANCE,
    "The value of the float " + "variable is %f, while the " +
    "value of the integer variable " + "is %d, and the string is %s%n", 
    floatVar, intVar, stringVar);

예제

다음 표에는 샘플 프로그램인 TestFormat.java에서 사용되는 몇 가지 컨버터와 플래그가 나와 있습니다.

ConverterFlagExplanation
d십진수입니다.
f부동 소수점.
n애플리케이션을 실행하는 플랫폼에 적합한 새 줄 문자. 항상 \n이 아닌 %n을 사용해야 합니다.
tB날짜 및 시간 변환-지역(locale)별 월의 전체 이름입니다.
td, te날짜 및 시간 변환 - 2자리 월의 요일. td는 필요에 따라 선행 0을 포함하지만 te는 포함하지 않습니다.
ty, tY날짜 및 시간 변환 - ty = 2자리 연도, tY = 4자리 연도.
tl날짜 및 시간 변환 시간(12시간 단위)입니다.
tM날짜 및 시간 변환-분(필요에 따라 선행 0 포함, 2자리)입니다.
tp날짜 및 시간 변환-지역(locale)별 오전/오후(소문자).
tm날짜 및 시간 변환 - 필요에 따라 선행 0을 포함한 2자리 숫자의 월입니다.
tD날짜 및 시간 변환 날짜 - %tm%td%ty
+양수든 음수든 부호를 포함합니다.
,로캘별 그룹화 문자를 포함합니다.
-왼쪽 정렬.
.3소수점 이하 세 자리.
10.3너비 10자, 오른쪽 맞춤, 소수점 이하 세 자리.

다음 프로그램은 서식으로 할 수 있는 몇 가지 서식을 보여줍니다. 출력은 임베드된 댓글에 큰따옴표 안에 표시됩니다:

import java.util.Calendar;
import java.util.Locale;
 
public class TestFormat {
    
    public static void main(String[] args) {
      long n = 461012;
      System.out.format("%d%n", n);      //  -->  "461012"
      System.out.format("%08d%n", n);    //  -->  "00461012"
      System.out.format("%+8d%n", n);    //  -->  " +461012"
      System.out.format("%,8d%n", n);    // -->  " 461,012"
      System.out.format("%+,8d%n%n", n); //  -->  "+461,012"
      
      double pi = Math.PI;
 
      System.out.format("%f%n", pi);       // -->  "3.141593"
      System.out.format("%.3f%n", pi);     // -->  "3.142"
      System.out.format("%10.3f%n", pi);   // -->  "     3.142"
      System.out.format("%-10.3f%n", pi);  // -->  "3.142"
      System.out.format(Locale.FRANCE,
                        "%-10.4f%n%n", pi); // -->  "3,1416"
 
      Calendar c = Calendar.getInstance();
      System.out.format("%tB %te, %tY%n", c, c, c); // -->  "May 29, 2006"
 
      System.out.format("%tl:%tM %tp%n", c, c, c);  // -->  "2:34 am"
 
      System.out.format("%tD%n", c);    // -->  "05/29/06"
    }
}

Note: 이 섹션의 논의는 formatprintf 메서드의 기본 사항만 다룹니다. 자세한 내용은 이 튜토리얼의 기본 I/O 섹션, “서식 지정” 페이지에서 확인할 수 있습니다. 문자열을 생성하기 위해 String.format()을 사용하는 것은 Strings에서 다룹니다.

 

DecimalFormat 클래스

앞뒤 0, 접두사 및 접미사, 그룹화(천 단위) 구분 기호, 소수점 구분 기호 표시를 제어하기 위해 java.text.DecimalFormat 클래스를 사용할 수 있습니다. DecimalFormat은 숫자 서식을 매우 유연하게 지정할 수 있지만 코드를 더 복잡하게 만들 수 있습니다.

다음 예제는 패턴 문자열을 DecimalFormat 생성자에 전달하여 DecimalFormat 객체 ‘myFormatter’를 생성합니다. 그런 다음 DecimalFormatNumberFormat에서 상속하는 format 메서드는 myFormatter에서 호출되며 이중 값을 인수로 받아 형식이 지정된 숫자를 문자열로 반환합니다.

다음은 DecimalFormat의 사용법을 설명하는 샘플 프로그램입니다:

import java.text.*;
 
public class DecimalFormatDemo {
 
   static public void customFormat(String pattern, double value ) {
      DecimalFormat myFormatter = new DecimalFormat(pattern);
      String output = myFormatter.format(value);
      System.out.println(value + "  " + pattern + "  " + output);
   }
 
   static public void main(String[] args) {
 
      customFormat("###,###.###", 123456.789);
      customFormat("###.##", 123456.789);
      customFormat("000000.000", 123.78);
      customFormat("$###,###.###", 12345.67);  
   }
}

The output is:

123456.789  ###,###.###  123,456.789
123456.789  ###.##  123456.79
123.78  000000.000  000123.780
12345.67  $###,###.###  $12,345.67

The following table explains each line of output.

패턴출력설명
123456.789###,###.###123,456.789파운드 기호(#)는 숫자를 나타내고 쉼표는 그룹 구분 기호를 위한 자리 표시자이며 마침표는 소수점 구분 기호를 위한 자리 표시자입니다.
123456.789###.##123456.79은 소수점 오른쪽에 세 자리가 있지만 패턴에는 두 자리만 있습니다. 포맷 메서드는 이를 반올림하여 처리합니다.
123.78000000.000000123.780파운드 기호(#) 대신 0 문자가 사용되므로 패턴은 선행 및 후행 0을 지정합니다.
12345.67$###,###.###$12,345.67패턴의 첫 번째 문자는 달러 기호($)입니다. 형식이 지정된 출력에서 가장 왼쪽 숫자 바로 앞에 온다는 점에 유의하세요.

 

기본 산술 그 이상

Java 프로그래밍 언어는 산술 연산자를 통해 기본 산술을 지원합니다: +, -, *, /, 그리고 %를 지원합니다. java.lang 패키지의 Math 클래스는 보다 고급 수학 연산을 위한 메서드와 상수를 제공합니다.

Math 클래스의 메서드는 모두 정적이므로 다음과 같이 클래스에서 직접 호출할 수 있습니다:

Math.cos(angle);

Note: 정적 임포트 언어 기능을 사용하면 모든 수학 함수 앞에 Math를 쓸 필요가 없습니다. import static java.lang.Math.*; 이렇게 하면 Math 클래스 메서드를 간단한 이름으로 호출할 수 있습니다. 예: cos(angle);

상수와 기본 메서드

Math 클래스에는 두 개의 상수가 포함되어 있습니다:

  • Math.E 자연 로그의 밑수 입니다.
  • Math.PI는 원의 둘레와 지름의 비율입니다.

Math 클래스에는 40개 이상의 정적 메서드도 포함되어 있습니다. 다음 표에는 몇 가지 기본 메서드가 나열되어 있습니다.

절대값 계산하기

값 라우딩

  • double ceil(double d): 인자보다 크거나 같은 가장 작은 정수를 반환합니다. double로 반환됩니다.
  • double floor(double d): 인자보다 작거나 같은 가장 큰 정수를 반환합니다. double로 반환됩니다.
  • double rint(double d): 인자와 가장 가까운 값을 가진 정수를 반환합니다. double로 반환됩니다.
  • long round(double d) and int round(float f): 메서드의 반환 타입에 표시된 대로 인자에 가장 가까운 long 또는 int를 반환합니다.

최소값 계산

최대값 계산

다음 프로그램인 BasicMathDemo는 이러한 방법 중 일부를 사용하는 방법을 설명합니다:

public class BasicMathDemo {
    public static void main(String[] args) {
        double a = -191.635;
        double b = 43.74;
        int c = 16, d = 45;
 
        System.out.printf("The absolute value " + "of %.3f is %.3f%n", 
                          a, Math.abs(a));
 
        System.out.printf("The ceiling of " + "%.2f is %.0f%n", 
                          b, Math.ceil(b));
 
        System.out.printf("The floor of " + "%.2f is %.0f%n", 
                          b, Math.floor(b));
 
        System.out.printf("The rint of %.2f " + "is %.0f%n", 
                          b, Math.rint(b));
 
        System.out.printf("The max of %d and " + "%d is %d%n",
                          c, d, Math.max(c, d));
 
        System.out.printf("The min of of %d " + "and %d is %d%n",
                          c, d, Math.min(c, d));
    }
}

이 프로그램의 출력은 다음과 같습니다:

The absolute value of -191.635 is 191.635
The ceiling of 43.74 is 44
The floor of 43.74 is 43
The rint of 43.74 is 44
The max of 16 and 45 is 45
The min of 16 and 45 is 16

지수 및 로그 메서드

다음 표에는 Math 클래스의 지수 및 로그 메서드가 나열되어 있습니다.

다음 프로그램인 ExponentialDemoe 값을 표시한 다음 임의로 선택한 숫자에 대해 이전 표에 나열된 각 메서드를 호출합니다:

public class ExponentialDemo {
    public static void main(String[] args) {
        double x = 11.635;
        double y = 2.76;
 
        System.out.printf("The value of " + "e is %.4f%n",
                          Math.E);
 
        System.out.printf("exp(%.3f) " + "is %.3f%n",
                          x, Math.exp(x));
 
        System.out.printf("log(%.3f) is " + "%.3f%n",
                          x, Math.log(x));
 
        System.out.printf("pow(%.3f, %.3f) " + "is %.3f%n",
                          x, y, Math.pow(x, y));
 
        System.out.printf("sqrt(%.3f) is " + "%.3f%n",
                          x, Math.sqrt(x));
    }
}

다음은 ExponentialDemo를 실행할 때 표시되는 출력입니다:

The value of e is 2.7183
exp(11.635) is 112983.831
log(11.635) is 2.454
pow(11.635, 2.760) is 874.008
sqrt(11.635) is 3.411

삼각함수

Math 클래스는 다음 표에 요약된 삼각 함수 컬렉션도 제공합니다. 이러한 각 메서드에 전달되는 값은 라디안으로 표현된 각도입니다. toRadians(double d) 메서드를 사용하여 각도에서 라디안으로 변환할 수 있습니다.

다음은 이러한 각 방법을 사용하여 45도 각도에 대한 다양한 삼각법 값을 계산하는 TrigonometricDemo라는 프로그램입니다:

public class TrigonometricDemo {
    public static void main(String[] args) {
        double degrees = 45.0;
        double radians = Math.toRadians(degrees);
        
        System.out.format("The value of pi " + "is %.4f%n",
                           Math.PI);
 
        System.out.format("The sine of %.1f " + "degrees is %.4f%n",
                          degrees, Math.sin(radians));
 
        System.out.format("The cosine of %.1f " + "degrees is %.4f%n",
                          degrees, Math.cos(radians));
 
        System.out.format("The tangent of %.1f " + "degrees is %.4f%n",
                          degrees, Math.tan(radians));
 
        System.out.format("The arcsine of %.4f " + "is %.4f degrees %n", 
                          Math.sin(radians), 
                          Math.toDegrees(Math.asin(Math.sin(radians))));
 
        System.out.format("The arccosine of %.4f " + "is %.4f degrees %n", 
                          Math.cos(radians),  
                          Math.toDegrees(Math.acos(Math.cos(radians))));
 
        System.out.format("The arctangent of %.4f " + "is %.4f degrees %n", 
                          Math.tan(radians), 
                          Math.toDegrees(Math.atan(Math.tan(radians))));
    }
}

이 프로그램의 출력은 다음과 같습니다:

The value of pi is 3.1416
The sine of 45.0 degrees is 0.7071
The cosine of 45.0 degrees is 0.7071
The tangent of 45.0 degrees is 1.0000
The arcsine of 0.7071 is 45.0000 degrees
The arccosine of 0.7071 is 45.0000 degrees
The arctangent of 1.0000 is 45.0000 degrees

 

난수

random() 메서드는 0.0에서 1.0 사이의 의사 무작위로 선택된 숫자를 반환합니다. 범위는 0.0을 포함하지만 1.0은 포함하지 않습니다. 다시 말해 0.0 <= Math.random() < 1.0 입니다. 다른 범위의 숫자를 얻으려면 무작위 메서드가 반환한 값에 산술을 수행하면 됩니다. 예를 들어 0에서 9 사이의 정수를 생성하려면 다음과 같이 작성합니다:

int number = (int)(Math.random() * 10);

값에 10을 곱하면 가능한 값의 범위는 0.0 <= 숫자 < 10.0이 됩니다.

하나의 난수를 생성해야 하는 경우 Math.random을 사용하면 잘 작동합니다. 난수를 여러 개 생성해야 하는 경우, java.util.Random의 인스턴스를 생성하고 해당 객체에서 메서드를 호출하여 숫자를 생성해야 합니다.