Programing

int를 16 진수로 다시 변환하는 Java

lottogame 2020. 11. 14. 09:43
반응형

int를 16 진수로 다시 변환하는 Java


다음 코드가 있습니다.

int Val=-32768;
String Hex=Integer.toHexString(Val);

이것은 ffff8000

int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex);  // Error "Invalid Int"

따라서 처음에는 -32768 값을 16 진수 문자열 ffff8000으로 변환하지만 16 진수 문자열을 다시 Integer로 변환 할 수 없습니다.

에서 .Net작동 나는 기대, 그리고 것입니다 returns -32768.

나는 이것을 직접 변환하기 위해 내 자신의 작은 방법을 작성할 수 있다는 것을 알고 있지만, 내가 뭔가를 놓치고 있는지 아니면 이것이 진짜 버그인지 궁금합니다.


숫자가 음수이기 때문에 오버플로됩니다.

이것을 시도하면 작동합니다.

int n = (int) Long.parseLong("ffff8000", 16);

int val = -32768;
String hex = Integer.toHexString(val);

int parsedResult = (int) Long.parseLong(hex, 16);
System.out.println(parsedResult);

그것이 당신이 할 수있는 방법입니다.

그것이 당신의 방식으로 작동하지 않는 이유 Integer.parseInt는 서명 된 int를 취하고 서명 toHexString되지 않은 결과 생성합니다. 따라서보다 높은 것을 삽입하면 0x7FFFFFF자동으로 오류가 발생합니다. long대신 파싱 하면 여전히 서명됩니다. 그러나 int로 다시 캐스팅하면 올바른 값으로 오버플로됩니다.


  • int 16 진수로 :

    Integer.toHexString(intValue);
    
  • 16 진수 int:

    Integer.valueOf(hexString, 16).intValue();
    

(값이 경계에 맞지 않는 경우) long대신 사용할 수도 있습니다 .intint

  • 16 진수 long:

    Long.valueOf(hexString, 16).longValue()
    
  • long 16 진수로

    Long.toHexString(longValue)
    

Java 8에는 메서드가 Integer.parseUnsignedInt있으며 Long.parseUnsignedLong원하는 작업을 수행 한다는 점을 언급 할 가치가 있습니다.

Integer.parseUnsignedInt("ffff8000",16) == -32768

이름은 16 진 문자열에서 부호있는 정수를 구문 분석하기 때문에 약간 혼란 스럽지만 작업을 수행합니다.


BigInteger 클래스를 사용해보십시오.

int Val=-32768;
String Hex=Integer.toHexString(Val);

//int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
//int SecondAttempt=Integer.decode("0x"+Hex);  // Error "Invalid Int"
BigInteger i = new BigInteger(Hex,16);
System.out.println(i.intValue());

Integer.toHexString (byte / integer)은 UTF-16 디코딩 문자와 같은 부호있는 바이트를 변환하려고 할 때 작동하지 않으므로 사용해야합니다.

Integer.toString(byte/integer, 16);

또는

String.format("%02X", byte/integer);

반대로 사용할 수 있습니다

Integer.parseInt(hexString, 16);

Java의 parseInt 메소드는 실제로 "false"hex를 먹는 코드입니다. -32768을 번역하려면 절대 값을 16 진수로 변환 한 다음 문자열 앞에 '-'를 추가해야합니다.

Integer.java 파일의 샘플이 있습니다.

public static int parseInt(String s, int radix)

설명은 매우 명확합니다.

* Parses the string argument as a signed integer in the radix 
* specified by the second argument. The characters in the string 
...
...
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255

사용 Integer.toHexString(...)하는 것이 좋은 대답입니다. 그러나 개인적으로 String.format(...).

이 샘플을 테스트로 사용해보십시오.

byte[] values = new byte[64];
Arrays.fill(values, (byte)8);  //Fills array with 8 just for test
String valuesStr = "";
for(int i = 0; i < values.length; i++)
    valuesStr += String.format("0x%02x", values[i] & 0xff) + " ";
valuesStr.trim();

헤헤, 궁금해. 말하자면 이것은 "의도적 인 버그"라고 생각합니다.

The underlying reason is how the Integer class is written. Basically, parseInt is "optimized" for positive numbers. When it parses the string, it builds the result cumulatively, but negated. Then it flips the sign of the end-result.

Example:

66 = 0x42

parsed like:

4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)

-64 - 2 = -66 (hex 2 parsed)

return -66 * (-1) = 66

Now, let's look at your example FFFF8000

16*(-1) = -16 (first F parsed)
-16*16 = -256 

-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352 

-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888

-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464 

-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552 

-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728). 
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.

Edit (addition): in order for the parseInt() to work "consistently" for -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, they would have had to implement logic to "rotate" when reaching -Integer.MAX_VALUE in the cumulative result, starting over at the max-end of the integer range and continuing downwards from there. Why they did not do this, one would have to ask Josh Bloch or whoever implemented it in the first place. It might just be an optimization.

However,

Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));

works just fine, for just this reason. In the sourcee for Integer you can find this comment.

// Accumulating negatively avoids surprises near MAX_VALUE

Below code would work:

int a=-32768;
String a1=Integer.toHexString(a);
int parsedResult=(int)Long.parseLong(a1,16);
System.out.println("Parsed Value is " +parsedResult);

참고URL : https://stackoverflow.com/questions/12005424/java-converting-int-to-hex-and-back-again

반응형