64-बिट विंडोज पर लंबे आकार का क्या है?


137

बहुत पहले नहीं, किसी ने मुझसे कहा कि long64 बिट मशीनों पर 64 बिट्स नहीं हैं और मुझे हमेशा उपयोग करना चाहिए int। इससे मुझे कोई मतलब नहीं था। मैंने डॉक्स देखा है (जैसे कि ऐप्पल की आधिकारिक साइट पर एक) कहते हैं कि long64-बिट सीपीयू के लिए संकलन करते समय वास्तव में 64 बिट्स होते हैं। मैंने देखा कि यह 64-बिट विंडोज पर क्या था और पाया

  • विंडोज: longऔर intलंबाई में 32-बिट रहते हैं, और 64-बिट पूर्णांक के लिए विशेष नए डेटा प्रकार परिभाषित किए जाते हैं।

( http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=3 से )

मुझे क्या उपयोग करना चाहिए? मैं की तरह कुछ परिभाषित करना चाहिए uw, swके रूप में एक ((अन) पर हस्ताक्षर किए चौड़ाई) longनहीं विंडोज पर हैं, और नहीं तो लक्ष्य सीपीयू bitsize पर एक जाँच करते हैं?


MSVC ++ के साथ विंडोज पर int और long 32-bit हैं: msdn.microsoft.com/en-us/library/3b2e7499.aspx । हालाँकि, उदाहरण के लिए वैक्टर को 4 जी से अधिक वस्तुओं को संग्रहीत करने की अनुमति देने के लिए, size_t 64 बिट है। तो एक को int64 के बजाय int64_t का उपयोग करने की आवश्यकता है जैसे कि वैक्टर जिसमें 4 जी से अधिक आइटम हो सकते हैं।
सर्ज रोजैच


@SergeRogatch वे size_tया itter प्रकार का उपयोग करना चाहिए iterate, नहीं intयाint64_t
phuclv

2
@ LưuV LnhPhúc, इसके साथ size_tनकारात्मक संख्याओं के निकट मुश्किल हो जाता है, क्योंकि size_tअहस्ताक्षरित है। तो for(size_t i=0; i<v.size()-2; i++)वेक्टर आकार 0 और 1. के लिए विफल रहता है एक और उदाहरण for(size_t i=v.size()-1; i>=0; i--):।
सर्ज रोजैच

2
यदि आप पॉइंटर्स पर गणित कर रहे हैं (अर्थात size_tमूल्यों के साथ तो परिणाम को एक ptrdiff_tप्रकार के चर में रखा जाना चाहिए - जो कि इस तरह के परिणाम को पकड़ने के लिए काफी बड़ा बनाया गया है और ठीक कारण के लिए एक हस्ताक्षरित प्रकार है!)
SlySven

जवाबों:


261

यूनिक्स दुनिया में, 64-बिट प्लेटफार्मों के लिए पूर्णांक और पॉइंटर्स के आकार के लिए कुछ संभव व्यवस्थाएं थीं। ज्यादातर व्यापक रूप से इस्तेमाल किए जाने वाले दो ILP64 थे (वास्तव में, इसका केवल कुछ ही उदाहरण हैं; क्रे एक ऐसा था) और LP64 (लगभग हर चीज के लिए)। संक्षेप from इंट, लॉन्ग, पॉइंटर्स 64-बिट ’और point लॉन्ग, पॉइंटर्स 64-बिट’ से आते हैं।

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

ILP64 प्रणाली को LP64 के पक्ष में छोड़ दिया गया (अर्थात, लगभग सभी बाद के प्रवेशकों ने LP64 का उपयोग किया, एस्पेन समूह की सिफारिशों के आधार पर, केवल 64-बिट ऑपरेशन की लंबी विरासत वाले सिस्टम एक अलग योजना का उपयोग करते हैं)। सभी आधुनिक 64-बिट यूनिक्स सिस्टम LP64 का उपयोग करते हैं। MacOS X और लिनक्स दोनों आधुनिक 64-बिट सिस्टम हैं।

Microsoft 64-बिट में परिवर्तन के लिए एक अलग योजना का उपयोग करता है: LLP64 ('लंबी लंबी, संकेत 64-बिट')। इसका अर्थ यह है कि 32-बिट सॉफ़्टवेयर को बिना परिवर्तन के पुनः चलाया जा सकता है। इसमें हर किसी के द्वारा अलग होने का अवगुण होता है, और 64-बिट कैपेसिटी के दोहन के लिए कोड को संशोधित करने की भी आवश्यकता होती है। हमेशा संशोधन आवश्यक था; यह यूनिक्स प्लेटफार्मों पर आवश्यक लोगों से संशोधन का एक अलग सेट था।

यदि आप अपने सॉफ़्टवेयर को प्लेटफ़ॉर्म-न्यूट्रल पूर्णांक प्रकार के नामों के आसपास डिज़ाइन करते हैं, तो संभवतः C99 <inttypes.h>हेडर का उपयोग करते हुए , जो, जब प्लेटफ़ॉर्म पर उपलब्ध प्रकार, हस्ताक्षरित (सूचीबद्ध) और अहस्ताक्षरित (सूचीबद्ध नहीं हैं, तो 'u' के साथ उपसर्ग):

  • int8_t - 8-बिट पूर्णांक
  • int16_t - 16-बिट पूर्णांक
  • int32_t - 32-बिट पूर्णांक
  • int64_t - 64-बिट पूर्णांक
  • uintptr_t - अहस्ताक्षरित पूर्णांक बड़े बिंदुओं को पकड़ने के लिए
  • intmax_t- प्लेटफ़ॉर्म पर पूर्णांक का सबसे बड़ा आकार (इससे बड़ा हो सकता है int64_t)

फिर आप इन प्रकारों का उपयोग करके अपने आवेदन को कोड कर सकते हैं जहां यह मायने रखता है, और सिस्टम प्रकारों के साथ बहुत सावधान रहना (जो अलग हो सकता है)। एक intptr_tप्रकार है - पॉइंटर्स रखने के लिए एक हस्ताक्षरित पूर्णांक प्रकार; आपको इसका उपयोग न करने, या केवल दो uintptr_tमानों ( ptrdiff_t) के घटाव के परिणाम के रूप में उपयोग करने की योजना बनानी चाहिए ।

लेकिन, जैसा कि सवाल बताता है (अविश्वास में), 64-बिट मशीनों पर पूर्णांक डेटा प्रकारों के आकार के लिए अलग-अलग प्रणालियां हैं। इस्की आद्त डाल लो; दुनिया बदलने वाली नहीं है।


12
जो लोग काफी लंबे समय से उपयोग कर रहे हैं, उनके लिए, 64-बिट संक्रमण में कुछ समानताएं हैं, जो 80 के दशक के मध्य -80 के दशक के 32-बिट संक्रमण के साथ हैं। ऐसे कंप्यूटर थे जो IL32 और अन्य थे जो L32 थे (पुरानी समस्या के लिए नए अंकन को स्वीकार करते हैं)। कभी 'इंट' 16-बिट था, कभी 32-बिट।
जोनाथन लेफ्लर

4
यह न भूलें कि यह केवल C-ish भाषाओं पर लागू होता है। अन्य लोगों के पास विशिष्ट विनिर्देश हैं जहां a) संकलक लेखक को डेटाटिप्स विली-निली या बी के आकार का चयन करने की अनुमति नहीं है) डेटाटिप्स के भौतिक प्रतिनिधित्व "लीक" या सी नहीं है) पूर्णांक हमेशा असीम रूप से बड़े होते हैं।
जोर्ग डब्ल्यू मित्तग

2
यह सच है - लेकिन उन भाषाओं के लिए जो व्यवहार को निर्दिष्ट करते हैं, पहली जगह में कोई समस्या नहीं है। उदाहरण के लिए, जावा में एक 'लंबा' है, लेकिन आकार सभी प्लेटफार्मों पर (64-बिट?) तय है। तो, 64-बिट मशीन में पोर्ट करने में कोई समस्या नहीं है; आकार नहीं बदलता है।
जोनाथन लेफ्लर 7

17
@TomFobear: ILP64 एक प्रमुख मुद्दा प्रस्तुत करता है - आप 32-बिट प्रकार को क्या कहते हैं? या, यदि आप 32-बिट प्रकार को shortकॉल करते हैं, तो आप 16-बिट प्रकार को क्या कहते हैं? और अगर आप charयूटीएफ -16 आदि के लिए 16-बिट प्रकार कहते हैं, तो आप 8-बिट प्रकार को क्या कहते हैं? तो, LP64 का उपयोग करके आप 8-बिट char, 16-बिट short, 32-बिट int, 64-बिट के साथ छोड़ देते हैंlonglong long जो प्रासंगिक हो जाने पर 128-बिट तक विस्तार के लिए कमरे के साथ होता है (यदि?) जो प्रासंगिक हो जाता है। उसके बाद, आपको सी की तुलना में 256 से अधिक शक्तियां मिली हैं ( intmax_tवैसे , मुझे लगता है कि आपके पास 256 बिट हो सकता है , और उसके बाद ही आप रन आउट होते हैं)। एलपी 64 में योग्यता है।
जोनाथन लेफ़लर

2
शायद यह आप लोगों के लिए स्पष्ट है, लेकिन मुझे लगता है कि यह ध्यान देने योग्य है कि C # हर चीज से अलग पूर्णांक आकार का उपयोग करता है। मैं हाल ही में एक DLL के साथ इंटरफेसिंग के साथ उलझ गया हूं क्योंकि C # 64-बिट लॉन्ग ( msdn.microsoft.com/en-us/library/ms173105.aspx ) का उपयोग करता है ।
कोम्फोलियो

57

यह स्पष्ट नहीं है कि सवाल Microsoft C ++ कंपाइलर या Windows API के बारे में है। हालाँकि, कोई [c ++] टैग नहीं है इसलिए मुझे लगता है कि यह Windows API के बारे में है। कुछ उत्तर लिंक रोट से पीड़ित हैं, इसलिए मैं अभी तक एक और लिंक प्रदान कर रहा हूं जो सड़ सकता है।


Windows API प्रकारों के बारे में जानकारी के लिए INT,LONG आदि वहाँ MSDN पर एक पृष्ठ है:

विंडोज डेटा प्रकार

जानकारी विभिन्न विंडोज हेडर फाइलों में भी उपलब्ध है, जैसे WinDef.h । मैंने यहां कुछ प्रासंगिक प्रकार सूचीबद्ध किए हैं:

प्रकार | एस / यू | x86 | 64
---------------------------- + ----- + -------- + ------ -
BYTE, BOOLEAN | यू | 8 बिट | 8 बिट
---------------------------- + ----- + -------- + ------ -
SHORT | एस | 16 बिट | 16 बिट
USHORT, WORD | यू | 16 बिट | 16 बिट
---------------------------- + ----- + -------- + ------ -
INT, लोंग | एस | 32 बिट | 32 बिट
UINT, ULONG, DWORD | यू | 32 बिट | 32 बिट
---------------------------- + ----- + -------- + ------ -
INT_PTR, LONG_PTR, LPARAM | एस | 32 बिट | 64 बिट
UINT_PTR, ULONG_PTR, WPARAM | यू | 32 बिट | 64 बिट
---------------------------- + ----- + -------- + ------ -
लोंगलांग | एस | 64 बिट | 64 बिट
उलॉन्गॉन्ग, QWORD | यू | 64 बिट | 64 बिट

कॉलम "S / U" हस्ताक्षरित / अहस्ताक्षरित है।


4

MSDN पर यह लेख कई प्रकार के उपनामों (विंडोज पर उपलब्ध) का संदर्भ देता है जो उनकी चौड़ाई के संबंध में थोड़ा अधिक स्पष्ट हैं:

http://msdn.microsoft.com/en-us/library/aa505945.aspx

उदाहरण के लिए, हालांकि आप 64-बिट अहस्ताक्षरित अभिन्न मान को संदर्भित करने के लिए ULONGLONG का उपयोग कर सकते हैं, आप UINT64 का उपयोग भी कर सकते हैं। (वही ULONG और UINT32 के लिए चला जाता है।) शायद ये थोड़ा साफ हो जाएगा?


1
क्या कोई गारंटी है कि uint32_t और DWORD विनिमेय होगा? यह कल्पना करना मुश्किल नहीं है कि वे नहीं हो सकते हैं [जैसे कि यदि पूर्व 32-बिट है intऔर बाद वाला 32-बिट है long, तो जीसीसी एक संकेतक को मान लेगा कि एक प्रकार उनके मिलान प्रतिनिधित्व के बावजूद दूसरे को उर्फ ​​करने में असमर्थ होगा]।
सुपरकैट

4

Microsoft ने पूर्णांक के लिए UINT_PTR और INT_PTR को भी परिभाषित किया है जो एक पॉइंटर के समान आकार के हैं।

यहां Microsoft विशिष्ट प्रकारों की एक सूची दी गई है - यह उनके ड्राइवर संदर्भ का हिस्सा है, लेकिन मेरा मानना ​​है कि यह सामान्य प्रोग्रामिंग के लिए भी मान्य है।


2

अपने कंपाइलर / प्लेटफॉर्म के लिए इसे जानने का सबसे आसान तरीका:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

8 से themultiplication बाइट्स से बिट्स प्राप्त करना है।

जब आपको किसी विशेष आकार की आवश्यकता होती है, तो अक्सर एक पुस्तकालय के पूर्वनिर्धारित प्रकारों में से एक का उपयोग करना सबसे आसान होता है। यदि यह अवांछनीय है, तो आप कर सकते हैं जो अक्सर ऑटोकॉन्फ़ सॉफ़्टवेयर के साथ होता है और कॉन्फ़िगरेशन सिस्टम में आवश्यक आकार के लिए सही प्रकार निर्धारित करता है।


4
ऐसा नहीं है कि यह मायने रखता है, लेकिन 8-बिट बाइट्स वास्तव में सी कल्पना का हिस्सा नहीं हैं (खंड 3.6 और सी मानक के 5.2.4.2.1)। यद्यपि आपको एक मशीन खोजने में मुश्किल होगी, जहां यह 8 बिट्स नहीं था, आप LONG_BIT को यह देखने के लिए देख सकते हैं कि आपका लंबा डेटाटाइप कितना बड़ा है।
एंड्रेस

बेशक, आप सही कह रहे हैं, यह वास्तव में वास्तुकला पर निर्भर है ("निष्पादन वातावरण के बुनियादी चरित्र सेट के किसी भी सदस्य को पकड़ने के लिए डेटा भंडारण की काफी बड़ी इकाई"), लेकिन सबसे अधिक इस्तेमाल किया जाने वाला आर्किटेक्चर जो 8 बिट्स के बराबर होता है।
पॉल डे व्रीज़

लेकिन ओपी ने अपने संकलक / मंच के बारे में नहीं पूछा ; उन्होंने विशेष रूप से 64-बिट विंडोज के बारे में पूछा - संभवतः इसलिए कि उनके पास परीक्षण करने के लिए 64-बिट विंडोज सिस्टम में सुविधाजनक पहुंच नहीं है।
कुक्सप्लसोन

0

longविंडोज प्लेटफॉर्म पर बिट्स का आकार 32 बिट्स (4 बाइट्स) है।

आप इसका उपयोग करके देख सकते हैं sizeof(long)


-2

यदि आपको कुछ निश्चित लंबाई के पूर्णांक का उपयोग करने की आवश्यकता है, तो आपको संभवतः आपकी मदद करने के लिए कुछ प्लेटफ़ॉर्म स्वतंत्र हेडर का उपयोग करना चाहिए। बूस्ट देखने में अच्छी जगह है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.