2012-08-17 80 views
48

我有以下代碼...的Java轉換INT爲十六進制,然後再返回

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轉換爲十六進制字符串ffff8000,但它不能將十六進制字符串轉換回整數。

.Net它的工作原理和我所預期的一樣,並且returns -32768

我知道我可以自己編寫自己的小方法來轉換它,但我只是想知道我是否錯過了某些東西,或者如果這真的是一個錯誤?

+1

可能都plicate [Java負int到十六進制失敗](http:// stackoverflow。com/questions/845230/java-negative-int-to-hex-and-back-failures) – 2012-08-17 12:17:38

+4

只是一個提示:由於約定變量名稱以小寫字母開頭:'in​​t firstAttempt = 5;' – Simulant 2012-08-17 12:20:24

回答

34

它溢出,因爲數字是負數。

試試這個,它會工作:

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

Thanks roni,that似乎是最好的解決方案。儘管Int.parseInt不能像我所期望的那樣工作,但它仍然顯得很古怪。 – 2012-08-17 12:36:20

+0

ffff8000不適合int(大於max int),這是一個正數(它是一個字符串,所以它只在負值時纔是負數) – roni 2012-08-17 12:40:51

+1

這是因爲parseInt使用帶符號的整數並且toHexString產生一個無符號的結果(看到我的回答)... – brimborium 2012-08-17 12:41:46

16
  • int爲十六進制:

    Integer.toHexString(intValue); 
    
  • 十六進制int

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

您可能還需要使用long代替int(如果該值不適合int範圍):

  • 十六進制long

    Long.valueOf(hexString, 16).longValue() 
    
  • long以十六進制

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

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

這就是你如何能做到這一點。

不按你的方式工作的原因:Integer.parseInt需要一個帶符號的整數,而toHexString產生一個無符號的結果。所以如果你插入高於0x7FFFFFF的東西,就會自動拋出一個錯誤。如果您將其解析爲long,則它仍將被簽名。但是當你把它轉換回int時,它會溢出到正確的值。

6

嘗試使用的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()); 
2

你應該知道,Java的parseInt函數的方法是actally的代碼吃「假」六角一串:如果你想翻譯-32768,你應該絕對值轉換爲十六進制,然後前面加上'字符串 - 」。

有一個Integer樣本。Java文件:

​​

的描述是相當明確的:

* 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 
1

呵呵,好奇。我認爲這是一個「天生的錯誤」,可以這麼說。

潛在的原因是如何編寫Integer類。基本上,對於正數,parseInt是「優化的」。當它解析字符串時,它累積地建立結果,但是否定。然後它翻轉最終結果的標誌。

例子:

66 =的0x42

解析,如:

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

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

return -66 * (-1) = 66 

現在,讓我們看看你的榜樣 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. 

編輯(加):爲了parseInt()爲「一致」工作,用於-Integer.MAX_VALUE < = n < = Integer.MAX_VALUE,當達到累計結果中的-Integer.MAX_VALUE時,它們必須實現邏輯以「旋轉」,從整數範圍的最大值開始並從那裏繼續向下。爲什麼他們沒有這樣做呢,人們不得不首先問Josh Bloch或者誰來實施它。這可能只是一個優化。

然而,

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

作品就好了,因爲這個原因。在Integer的源代碼中你可以找到這個評論。

// Accumulating negatively avoids surprises near MAX_VALUE 
+2

'//累積消極地避免了MAX_VALUE附近的驚喜 - >但它引入了驚人的降低0 ^^ – brimborium 2012-08-17 13:07:17

6

值得一提的是,Java的8所擁有的方法Integer.parseUnsignedIntLong.parseUnsignedLong已經做了你想要的東西,具體是:

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

名字是有點混亂,因爲它分析從一個有符號整數一個十六進制字符串,但它的工作。

1

使用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(); 
2

由於Integer.toHexString(字節/整數),當你試圖符號字節轉換像UTF-16解碼後的字符不工作,你必須使用:

Integer.toString(byte/integer, 16); 

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

反向您可以使用

Integer.parseInt(hexString, 16); 
相關問題