क्या जावा छोटे एंडियन या बड़े एंडियन में पूर्णांक पढ़ता है?


94

मैं पूछता हूं क्योंकि मैं एक सी प्रक्रिया से एक जावा को बाइट स्ट्रीम भेज रहा हूं। सी तरफ 32 बिट पूर्णांक में एलएसबी पहला बाइट है और एमएसबी 4 वां बाइट है।

तो मेरा सवाल यह है कि जब हम सी प्रक्रिया से भेजे गए थे तो जावा पक्ष पर, जावा प्रक्रिया पर एंडियन क्या है ?

एक अनुवर्ती प्रश्न: यदि जावा पक्ष में एंडियन एक ही नहीं है, जो मुझे भेजा गया है, तो मैं उनके बीच कैसे बदल सकता हूं?


1
यहाँ इसके लिए मेरा शब्दांश है इसलिए मैं यह नहीं भूलूंगा: जावा कोई हार्डवेयर नहीं है, बल्कि आभासी है, इंटरनेट की भाषा है। नेटवर्क बाइट क्रम है बड़ा endian । इसलिए, जावा बड़ा एंडियन है
21

जवाबों:


66

नेटवर्क बाइट ऑर्डर (बड़ा एंडियन) का उपयोग करें, जो वैसे भी जावा का उपयोग करता है। सी में विभिन्न अनुवादकों के लिए आदमी htons देखें।


अब मैं अपने linux बॉक्स में नहीं हूँ, लेकिन htons एक मानक लिबास में से एक है?
हफीज

H30097.www3.hp.com/docs//base_doc/DOCUMENTATION/V51_HTML/MAN/… के अनुसार इसका मानक c लाइब्रेरी का हिस्सा है, हाँ
Egil

1
htons लगभग हर जगह उपलब्ध है, लेकिन यह ISO C. में नहीं है
MSalters

1
यदि आपको नेटवर्क बाइट ऑर्डर के अलावा किसी और चीज़ का उपयोग करना है, तो आप या तो अपने आप को बिटवाइज़ ऑपरेटर्स के साथ रोल करें या java.nio.Buffer के विभिन्न संस्करणों का उपयोग करें
डैरन

1
इसके मैन-पेज के अनुसार इसे POSIX.1 में परिभाषित किया गया है, इसलिए यह हर जगह उपलब्ध होना चाहिए। और मुझे यह Win32 में उपयोग करने के लिए याद है, इसलिए यह सिर्फ POSIX सिस्टम पर नहीं है।
जोकिम सॉर

47

मैं गूगल के माध्यम से यहाँ ठोकर खाई और मुझे जवाब मिला कि जावा बड़ा एंडियन है

प्रतिक्रियाओं के माध्यम से पढ़कर मैं बताना चाहूंगा कि बाइट्स में वास्तव में एंडियन ऑर्डर होता है, हालांकि दयापूर्वक, यदि आपने केवल "मुख्यधारा" माइक्रोप्रोसेसरों के साथ निपटा है, तो आप कभी भी इसे इंटेल, मोटोरोला और ज़िलॉग के रूप में सामना करने की संभावना नहीं रखते हैं उनके UART चिप्स की शिफ्ट दिशा पर सहमति व्यक्त की और कहा कि एक बाइट का MSB होगा 2**7और LSB 2**0उनके CPU में होगा (मैंने इस सामग्री का उपयोग करने पर जोर देने के लिए FORTRAN पावर नोटेशन का उपयोग किया है:)।

मैं 20 साल पहले कुछ स्पेस शटल बिट सीरियल डाउनलिंक डेटा के साथ इस मुद्दे पर भाग गया था जब हमने मैक कंप्यूटर के साथ $ 10K इंटरफ़ेस हार्डवेयर को बदल दिया था। इसके बारे में नासा टेक ब्रीफ प्रकाशित हुआ है। मैं बस एक बिट का उपयोग कर रहा हूँ एक बिट के साथ तालिका उलट ( table[0x01]=0x80आदि) के बाद तालिका में प्रत्येक स्ट्रीम को बिट स्ट्रीम से स्थानांतरित कर दिया गया था।


महान अंतर्दृष्टि! मेरे पास यह प्रश्न है और वेब में इसका कोई उत्तर नहीं है।
13:28

अगर उनमें से कोई भी सार्वजनिक है, तो क्या आप नासा के तकनीकी संक्षिप्त (और पेट्स स्पेस शटल बिट सीरियल डाउनलिंक डेटा) के बारे में बात कर सकते हैं? आकर्षक होगा, मैंने कभी ऐसा नहीं देखा।
n611x007

3
बिटवाइज़ एंडियननेस भी संपीड़न प्रारूपों के साथ खेल में आता है जो हफ़मैन एन्कोडिंग के कुछ रूप का उपयोग करते हैं (अर्थात वे सभी)। अतिरिक्त मज़ा के लिए, जेपीईजी "बिटवाइज़ बिग-एंडियन" है (यानी सबसे महत्वपूर्ण बिट "पहला" बिट है) और एलजेड "बिटवाइज़ लिटिल-एंडियन" है। मैंने एक बार एक मालिकाना संपीड़न प्रारूप पर काम किया था जो हुड के नीचे दोनों प्रारूपों का उपयोग करता था। ओह, यह मजेदार था ...
user435779

बिट्स में शुरू होने के बाद, मैंने सोचा कि लंबे समय से यह धीरज था।
रॉय फॉक

20

जावा में कोई अहस्ताक्षरित पूर्णांक नहीं हैं। सभी पूर्णांकों पर हस्ताक्षर किए गए हैं और बड़े एंडियन में हैं।

C की तरफ प्रत्येक बाइट में tn LSB है, जिसके शुरू में बाईं ओर MSB है और अंत में MSB है।

ऐसा लगता है कि आप एलएसबी का उपयोग कम से कम महत्वपूर्ण रूप से कर रहे हैं, क्या आप हैं? एलएसबी आमतौर पर कम से कम महत्वपूर्ण बाइट के लिए खड़ा है। एंडियनस बिट आधारित नहीं है, लेकिन बाइट आधारित है।

अहस्ताक्षरित बाइट से जावा पूर्णांक में बदलने के लिए:

int i = (int) b & 0xFF;

अहस्ताक्षरित 32-बिट लिटिल-एंडियन से बाइट में बदलने के लिए [] जावा लंबे (मेरे सिर के ऊपर से, परीक्षण नहीं किया गया है):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;

बस एहसास हुआ कि: $ इसलिए मैं कैसे इस अहस्ताक्षरित छोटे एंडियन को मेरी जावा प्रक्रिया को सही ढंग से पढ़ने के लिए भेजने वाला हूं?
हफीज

whay मेरा मतलब शुरुआत से है कि lsb 4 बाइट्स की शुरुआत में है (यह अहस्ताक्षरित 32 बिट int है) तो मेरा मतलब था कम से कम महत्वपूर्ण बाइट
hhafez

इसके अलावा मैं C -> Java से जावा -> C :)
hhafez

आपका कोड ठीक काम करता है, इसलिए जब तक आप अंतिम तीन पंक्तियों में 0xFF के बाद अर्ध-बृहदान्त्र को हटा नहीं देते। मैं इसे स्वयं संपादित करूंगा, लेकिन यह 6 वर्णों से कम का परिवर्तन है।
मूस मोरल्स

1
लगभग 8 साल लग गए लेकिन आखिरकार किसी ने वाक्य रचना त्रुटि को देखा। धन्यवाद @MooseMorals :)
जोनास

12

इसका कोई तरीका नहीं है कि यह जावा में कुछ भी प्रभावित कर सकता है, क्योंकि कुछ बाइट्स को सीधे जावा में एक इंट में मैप करने का कोई (प्रत्यक्ष गैर-एपीआई) तरीका नहीं है।

प्रत्येक एपीआई जो ऐसा करता है या ऐसा ही कुछ व्यवहार को बहुत सटीक रूप से परिभाषित करता है, इसलिए आपको उस एपीआई के प्रलेखन को देखना चाहिए।


3
ओह यकीन है कि वहाँ है बाइनरी गणित (;; |, <<, आदि) बाइट्स और इन्ट्स पर ठीक काम करता है। मनमाने बाइट्स लेना और उन्हें पूर्णांक में रखना काफी आसान है।
हर्म्स

8
लेकिन अगर आप ऐसा करते हैं, तो आप अभी भी यह नहीं बता सकते हैं कि आपका जेवीएम आंतरिक रूप से क्या उपयोग करता है।
डैरन

4
हां, लेकिन वहां भी आप सीधे मैपिंग नहीं कर रहे हैं। आप अंकगणित का उपयोग कर रहे हैं जो वास्तव में आप इसे बताते हैं, इसमें कोई अस्पष्टता नहीं है। C में आप हमेशा एक "बाइट *" को "लॉन्ग *" में डाल सकते हैं और इसे डी-रेफरेंस कर सकते हैं। फिर आपको धीरज की परवाह करनी होगी। जावा में ऐसा करने का कोई प्रत्यक्ष, अस्पष्ट तरीका नहीं है।
जोकिम सौअर

ओह समझा। आप कलाकारों के बारे में बात कर रहे थे, न कि बाइनरी गणित के बारे में। हाँ, उस मामले में आप सही हैं।
हर्म्स

10
+1 के लिए "डॉक्यूमेंटेशन देखें", लेकिन ध्यान दें: 1 वाक्य अब सही नहीं है क्योंकि आजकल NIO पैकेज बाइटबफ़र प्रदान करता है जो बाइट को प्राइमेटिक्स में मैप कर सकता है और जहाँ आप बाइट ऑर्डर को बदल सकते हैं। देखें ByteBuffer और byteorder
user85421

3

मैं एक-एक करके बाइट्स पढ़ता हूं, और उन्हें लंबे मूल्य में संयोजित करता हूं । इस तरह आप एंडियननेस को नियंत्रित करते हैं, और संचार प्रक्रिया पारदर्शी होती है।


इस पर टिप्पणी करने की परवाह करें कि आप मुझे वोट क्यों दे रहे हैं?
राउटर लिवेन्स

क्योंकि यहां तक ​​कि अगर मैं प्रत्येक बाइट को व्यक्तिगत रूप से पढ़ता हूं तो भेजी गई बाइट की समाप्ति गलत होगी, इसलिए मुझे इसे परिवर्तित करने की आवश्यकता होगी
hhafez

23
एक बाइट की समाप्ति? आख़िर ये बला है क्या? शब्दों के प्रति संवेदनशील होते हैं, अलग-अलग बाइट्स नहीं।
राउटर लिवेंस

3
@ ह्हाफेज़ यह सच नहीं है, बाइट्स में धीरज नहीं होता है क्योंकि हमें बाइट पढ़ते समय चिंतित होने की आवश्यकता होती है, आप, प्रोग्रामर उचित जगह पर बाइट्स असाइन करने के लिए जिम्मेदार हैं। यह वास्तव में DataInputStream क्या करता है, यह सिर्फ हूड्स के नीचे एक बड़े एंडियन तरीके से बाइट्स को एक साथ जोड़ता है।
ओपन स्कूल

2
@WouterLievens: मैंने कुछ I / O उपकरणों (जैसे कि एक वास्तविक समय की घड़ी चिप) का सामना किया है, जो भी किसी भी कारण से, बिट-उलटा प्रारूप में डेटा भेजते हैं; उनसे डेटा प्राप्त करने के बाद, प्रत्येक बाइट में बिट्स को उल्टा करना आवश्यक है। मैं आपसे सहमत हूं, हालांकि, बाइट्स का एंडियन-नेस आम तौर पर एक मुद्दा नहीं है, जब तक कि किसी को हार्डवेयर के विशेष रूप से डिजाइन किए गए टुकड़ों के साथ सौदा नहीं करना पड़ता है।
सुपरकैट

3

यदि यह आपके द्वारा उपयोग किए जाने वाले प्रोटोकॉल को फिट करता है, तो DataInputStream का उपयोग करने पर विचार करें, जहां व्यवहार बहुत अच्छी तरह से परिभाषित किया गया है


1
वह केवल यही कर सकता है कि यदि उसका प्रोटोकॉल उसी अंतःकरण का उपयोग करता है।
राउटर लिवेन्स

मैंने लिंक को ठीक किया, और इसे जावा 9, वर्तमान रिलीज़ को इंगित करने के लिए बदल दिया। प्रश्न में एपीआई को जावा 1.0 में पेश किया गया था, हालांकि।
जेन्स बैनमैन

2

जैसा कि ऊपर बताया गया है कि जावा 'बिग-एंडियन' है। इसका मतलब है कि यदि आप मेमोरी (इंटेल सीपीयू पर कम से कम) की जांच करते हैं, तो इंट का एमएसबी बाईं ओर है। साइन बिट सभी जावा पूर्णांक प्रकारों के लिए MSB में भी है।
'लिटिल-एंडियन' सिस्टम द्वारा संग्रहीत बाइनरी फ़ाइल से 4 बाइट अहस्ताक्षरित पूर्णांक को पढ़ना जावा में अनुकूलन का एक सा लगता है। DataInputStream की readInt () बिग-एंडियन प्रारूप की अपेक्षा करती है।
यहाँ एक उदाहरण है कि एक चार बाइट अहस्ताक्षरित मान (1 के रूप में HexEdit 01 00 00 00 के रूप में प्रदर्शित होता है) को 1 के मान के साथ पूर्णांक में पढ़ता है:

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }

"ऊपर उल्लिखित" क्या संदर्भित करता है? जिस क्रम में SO उत्तर प्रदर्शित होते हैं, वह भिन्न हो सकता है।
LarsH

0

जावा बल वास्तव में बड़ा एंडियन: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11


3
यह बाइटकोड निर्देशों के अंतरण के बारे में है, रनटाइम पर डेटा की समाप्ति के बारे में नहीं।
काया

मैं मतदान कर रहा हूं। इस स्निपेट byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array();ने एक ऐसी byteसरणी का C/C++निर्माण किया जो मेरे द्वारा उत्पादित की गई चीज़ों का उल्टा है । इसलिए, रनटाइम पर डेटा में भी जावा का बड़ा धीरज प्रभावी होता है।
21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.