[java] Java 8 및 Java 9에서 서명되지 않은 정수를 사용하는 방법은 무엇입니까?

Oracle “Primitive data types” 페이지 에서 Java 8이 서명되지 않은 int 및 long에 대한 지원을 추가한다고 언급합니다.

int: 기본적으로 int데이터 유형은 32 비트 부호있는 2의 보수 정수이며, 최소값은 −2 31 이고 최대 값은 2 31 −1입니다. Java SE 8 이상에서는 int데이터 유형을 사용하여 최소값이 0이고 최대 값이 2 32 -1 인 부호없는 32 비트 정수를 나타낼 수 있습니다 . 데이터 유형을 부호없는 정수로 사용하려면 Integer클래스를 사용 하십시오 int. 자세한 내용은 The Number Classes 섹션을 참조하십시오. 같은 정적 방법 compareUnsigned, divideUnsigned등이 첨가 된 Integer부호없는 정수에 대한 산술 연산을 지원하는 클래스.

long: long데이터 유형은 64 비트 2의 보수 정수입니다. 부호 long있는 값은 최소값 -2 63 이고 최대 값은 2 63 -1입니다. Java SE 8 이상에서는 long데이터 유형을 사용하여 long최소값이 0이고 최대 값이 2 64 -1 인 부호없는 64 비트를 나타낼 수 있습니다 . int에서 제공하는 것보다 더 넓은 값 범위가 필요한 경우이 데이터 유형을 사용하십시오. Long클래스는 방법이 좋아 포함 compareUnsigned, divideUnsigned서명에 대한 산술 연산을 지원하는 등 long.

그러나 부호없는 long 또는 정수를 선언하는 방법을 찾지 못했습니다. 예를 들어, 다음 코드는 범위 내에 있어야 할 때 “리터럴이 범위를 벗어났습니다”(물론 Java 8을 사용하고 있음)라는 컴파일러 오류 메시지를 제공합니다 (할당 된 값은 정확히 2 64 -1입니다). :

public class Foo {
    static long values = 18446744073709551615L;

    public static void main(String[] args){
        System.out.println(values);
    }
}

그렇다면 unsigned int 또는 long을 선언하는 방법이 있습니까?



답변

게시 한 문서 와이 블로그 게시물 에 따라 서명되지 않은 int / long과 서명 된 int / long 사이의 기본 요소를 선언 할 때 차이가 없습니다. “새로운 지원”은 Integer 및 Long 클래스 (예 : Integer.divideUnsigned)에 정적 메서드가 추가 된 것입니다 . 이러한 방법을 사용하지 않는 경우 2 ^ 63-1보다 긴 “unsigned”는 음수 값을 가진 평범한 오래된 long입니다.

간단히 훑어 보면 +/- 2 ^ 31-1 또는 long의 경우 +/- 2 ^ 63-1 범위를 벗어난 정수 상수를 선언하는 방법이없는 것 같습니다. 범위를 벗어난 양수 값에 해당하는 음수 값을 수동으로 계산해야합니다.


답변

음, 심지어 자바 (8)에, long그리고 int아직 서명, 일부 방법은 그들이 서명되지 않은 것처럼 그들을 치료 . 그렇게 서명되지 않은 long리터럴 을 작성 하려면 다음을 수행하십시오.

static long values = Long.parseUnsignedLong("18446744073709551615");

public static void main(String[] args) {
    System.out.println(values); // -1
    System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}


답변

    // Java 8
    int vInt = Integer.parseUnsignedInt("4294967295");
    System.out.println(vInt); // -1
    String sInt = Integer.toUnsignedString(vInt);
    System.out.println(sInt); // 4294967295

    long vLong = Long.parseUnsignedLong("18446744073709551615");
    System.out.println(vLong); // -1
    String sLong = Long.toUnsignedString(vLong);
    System.out.println(sLong); // 18446744073709551615

    // Guava 18.0
    int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
    System.out.println(vIntGu); // -1
    String sIntGu = UnsignedInts.toString(vIntGu);
    System.out.println(sIntGu); // 4294967295

    long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
    System.out.println(vLongGu); // -1
    String sLongGu = UnsignedLongs.toString(vLongGu);
    System.out.println(sLongGu); // 18446744073709551615

    /**
     Integer - Max range
     Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1
     Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1

     Long - Max range
     Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1
     Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1
     */


답변

Java 8 또는 Java 9에서 unsigned long 또는 int 를 선언 하는 방법은 없습니다. 그러나 일부 메소드는이를 서명되지 않은 것처럼 처리합니다. 예를 들면 다음과 같습니다.

static long values = Long.parseUnsignedLong("123456789012345678");

그러나 이것은 변수의 선언 이 아닙니다 .


답변

타사 라이브러리를 사용하는 옵션 인 경우가 jOOU (에서 라이브러리 오프 스핀 jOOQ ), 자바 부호없는 정수 숫자 유형의 래퍼 이벤트. 이것은 서명되지 않은 유형에 대한 기본 유형 (따라서 바이트 코드) 지원을 갖는 것과 똑같은 것은 아니지만 아마도 사용 사례에는 충분할 것입니다.

import static org.joou.Unsigned.*;

// and then...
UByte    b = ubyte(1);
UShort   s = ushort(1);
UInteger i = uint(1);
ULong    l = ulong(1);

이러한 유형은 모두 확장 java.lang.Number되며 상위 기본 유형 및 BigInteger.

(면책 조항 : 저는이 도서관 뒤에있는 회사에서 일합니다)


답변