जावा फिर से हेक्स और वापस करने के लिए int परिवर्तित


80

मेरे पास निम्नलिखित कोड है ...

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

मुझे पता है कि मैं इसे बदलने के लिए अपनी खुद की छोटी विधि लिख सकता हूं, लेकिन मैं सोच रहा हूं कि क्या मुझे कुछ याद आ रहा है, या अगर यह वास्तव में एक बग है?



5
बस एक संकेत: जैसा कि कन्वेंशन वैरिएबल नाम एक कम केस कैरेक्टर से शुरू होता है:int firstAttempt = 5;
सिमुलेंट

जवाबों:


48

यह ओवरफ्लो करता है, क्योंकि संख्या नकारात्मक है।

यह कोशिश करो और यह काम करेगा:

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

धन्यवाद रोनी, यह सबसे अच्छा समाधान लगता है। हालांकि यह अभी भी अजीब लगता है कि Int.parseInt काम नहीं करता है जैसा कि मुझे उम्मीद है।
रिच एस

ffff8000 एक इंट (बड़े और अधिकतम इंट) में फिट नहीं होता है, यह एक सकारात्मक संख्या है (यह एक स्ट्रिंग है तो यह ऋणात्मक होने पर केवल ऋणात्मक है)
रोनी बार यानाई

1
ऐसा इसलिए है क्योंकि parseInt एक हस्ताक्षरित int लेता है और toHexString एक अहस्ताक्षरित परिणाम उत्पन्न करता है (मेरा उत्तर देखें) ...
brimborium

धन्यवाद u मेरा दिन बचा लिया :)
विनेश TP

1
@roni, अगर हेक्स स्ट्रिंग मूल्य का है, String Hex=Integer.toHexString("xyz");तो हेक्स से "स्ट्रिंग" के रूप में वापस स्ट्रिंग कैसे प्राप्त करें
सुबोध

73
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इसके बजाय इसे पार्स करते हैं , तो भी यह हस्ताक्षरित होगा। लेकिन जब आप इसे वापस इंट में डालते हैं, तो यह सही मूल्य पर बह जाएगा।


27
  • int हेक्स के लिए:

    Integer.toHexString(intValue);
    
  • हेक्स को int:

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

आप longइसके बजाय उपयोग करना चाह सकते हैं int(यदि मूल्य intसीमा के लायक नहीं है ):

  • हेक्स को long:

    Long.valueOf(hexString, 16).longValue()
    
  • long हेक्स को

    Long.toHexString(longValue)
    

9

यह उल्लेखनीय है कि जावा 8 में वे विधियाँ हैं Integer.parseUnsignedIntऔर Long.parseUnsignedLongजो आपको विशेष रूप से चाहिए थीं:

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

नाम थोड़ा भ्रामक है, क्योंकि यह एक हेक्स स्ट्रिंग से एक हस्ताक्षरित पूर्णांक को पार्स करता है, लेकिन यह काम करता है।


7

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());

4

जब आप UTF-16 डिकोड किए गए वर्णों का उपयोग करने की कोशिश कर रहे हों, तो Integer.toHexString (बाइट / पूर्णांक) काम नहीं कर रहा है:

Integer.toString(byte/integer, 16);

या

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

रिवर्स आप उपयोग कर सकते हैं

Integer.parseInt(hexString, 16);

3

Java का parseInt विधि वास्तव में "गलत" हेक्स खाने वाले कोड का एक गुच्छा है: यदि आप -32768 का अनुवाद करना चाहते हैं, तो आपको निरपेक्ष मान को हेक्स में परिवर्तित करना चाहिए, फिर स्ट्रिंग को '-' के साथ प्रीपेन्ड करें।

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

2

का उपयोग करना 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

नीचे कोड काम करेगा:

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

1

हे, जिज्ञासु। मुझे लगता है कि यह एक "जानबूझकर बग" है, इसलिए बोलने के लिए।

अंतर्निहित कारण यह है कि इंटेगर वर्ग कैसे लिखा जाता है। मूल रूप से, 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 में पहुंचते हैं तो उन्हें "रोटेट" करना होगा। संचयी परिणाम, पूर्णांक सीमा के अधिकतम छोर पर शुरू होता है और वहां से नीचे की ओर जारी रहता है। उन्होंने ऐसा क्यों नहीं किया, जोश बलोच से पूछना होगा या जिसने भी इसे पहले स्थान पर लागू किया है। यह सिर्फ एक अनुकूलन हो सकता है।

तथापि,

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

बस ठीक काम करता है, सिर्फ इस कारण से। इंटेगर के लिए स्रोत में आप इस टिप्पणी को पा सकते हैं।

// Accumulating negatively avoids surprises near MAX_VALUE

2
// Accumulating negatively avoids surprises near MAX_VALUE-> लेकिन यह आश्चर्यचकित करता है कम 0 ^ ^
ब्रिम्बोरियम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.