क्या 0 और -0 के बीच अंतर करना संभव है?


94

मुझे पता है कि पूर्णांक मूल्य 0और -0अनिवार्य रूप से समान हैं। लेकिन, मैं सोच रहा हूं कि क्या उनके बीच अंतर करना संभव है।

उदाहरण के लिए, मुझे कैसे पता चलेगा कि एक चर सौंपा गया था -0?

bool IsNegative(int num)
{
    // How ?
}

int num = -0;
int additinon = 5;

num += (IsNegative(num)) ? -addition : addition;

क्या -0स्मृति में सहेजा गया मान ठीक उसी तरह है जैसे 0?


9
पूर्णांकों के लिए, कोई अंतर नहीं है।
मारून

14
यह कार्यान्वयन पर निर्भर करता है, लेकिन कार्यान्वयन के लिए जहां int2 के पूरक में प्रतिनिधित्व किया जाता है (अब तक सबसे आम तौर पर सामना किया गया है), 0और -0समान बिटकॉइन सत्यापन हैं।
मकारसे

11
2 के पूरक मशीन में बिट-स्तर पर कोई अंतर नहीं है।
मार्को ए।

17
@VirtualSnake: "बाइनरी में" का क्या अर्थ है? कर रहे हैं, वास्तव में, द्विआधारी एन्कोडिंग जिसके लिए वहाँ है एक अंतर के बीच -0 और 0. साइन और परिमाण, उदाहरण के लिए।
बेंजामिन लिंडले

8
@VirtualSnake यह सही है, हम बात कर रहे हैं int। देखें ओन्स की पूरक एन्कोडिंग
सियापन

जवाबों:


112

यह उस मशीन पर निर्भर करता है जिसे आप लक्षित कर रहे हैं।

एक मशीन पर जो पूर्णांक के लिए 2 के पूरक प्रतिनिधित्व का उपयोग करता है , बिट-स्तर के बीच कोई अंतर नहीं है0 और -0(उनका समान प्रतिनिधित्व है)

यदि आपकी मशीन किसी के पूरक का उपयोग करती है , तो आप निश्चित रूप से कर सकते हैं

0000 0000   -> signed01111 1111   -> signed   0

जाहिर है हम मूल समर्थन का उपयोग करने के बारे में बात कर रहे हैं , x86 श्रृंखला प्रोसेसर के पास हस्ताक्षरित संख्याओं के पूरक प्रतिनिधित्व के लिए मूल समर्थन है। अन्य अभ्यावेदन का उपयोग करना निश्चित रूप से संभव है लेकिन शायद कम कुशल होगा और अधिक निर्देशों की आवश्यकता होगी।

(जैसा कि जेरीकॉफिन ने भी नोट किया है: भले ही किसी के पूरक को ज्यादातर ऐतिहासिक कारणों से माना जाता है, हस्ताक्षरित परिमाण प्रतिनिधित्व अभी भी काफी सामान्य हैं और नकारात्मक और सकारात्मक शून्य के लिए एक अलग प्रतिनिधित्व है)


6
@TobiMcNamobi: कभी भी इस बारे में चिंतित होने की संभावना नहीं है। अगर किसी ने कभी भी मशीन के लिए C ++ कंपाइलर पोर्ट करने की जहमत उठाई हो तो मुझे आश्चर्य होगा।
बेंजामिन लिंडले

1
मैं बेंजामिन से सहमत हूं, ऐतिहासिक रूप से इसका उपयोग करने वाली मशीनें हैं, लेकिन आजकल मैं उत्पादन मशीनों को जानने के लिए नहीं होता हूं जो इसका उपयोग करते हैं। फिर भी यह जानना और ध्यान में रखना हमेशा अच्छा होता है।
मार्को ए।

4
@TobiMcNamobi एक का पूरक अभी भी UNISYS 2200 सिस्टम में मौजूद है stackoverflow.com/a/12277974/995714 stackoverflow.com/q/6971886/995714
phuclv

2
मैं किसी के पूरक आवश्यकताओं पर कभी नहीं देखा है - करता मानक वास्तव में गारंटी नहीं है कि 0और -0कर रहे हैं अलग ? मैंने ईमानदारी से यह अपेक्षा की है कि यह एक ही मूल्य के दो बिट अभ्यावेदन की अनुमति देने के समान व्यवहार करेगा, और आपका कार्यक्रम जो भी ऐसा लगता है, का उपयोग कर सकता है।

8
@ हुरली: नहीं, भले ही एक नकारात्मक शून्य प्रतिनिधित्व मौजूद हो, मानक इस बात की गारंटी नहीं देता है कि अभिव्यक्ति का उपयोग करते हुए असाइनमेंट या आरंभीकरण -0, यह कहना है कि यूनियर -ऑपरेटर को पूर्णांक स्थिरांक पर लागू करने का परिणाम 0एक नकारात्मक शून्य प्रतिनिधित्व है। प्रतिनिधित्व के बावजूद, मानक कभी नहीं कहता है 0और -0गणितीय रूप से अलग-अलग मूल्य हैं, केवल यह कि एक नकारात्मक-शून्य बिट पैटर्न हो सकता है। अगर वहाँ है, यह अभी भी एक ही संख्यात्मक मूल्य का प्रतिनिधित्व करता है, 0.
स्टीव जेसप

14

एक int(लगभग-सार्वभौमिक "2 के पूरक" प्रतिनिधित्व में) के प्रतिनिधित्व हैं 0और -0समान हैं। (वे अन्य संख्या प्रतिनिधित्वों के लिए भिन्न हो सकते हैं, उदाहरण के लिए। IEEE 754 फ़्लोटिंग पॉइंट।)


9
>> 2 के पूरक प्रतिनिधित्व को मानते हुए
मार्को ए।

12

आइए 2 के पूरक में 0 का प्रतिनिधित्व करने के साथ शुरू करें (निश्चित रूप से कई अन्य प्रणालियों और प्रतिनिधित्व मौजूद हैं, यहां मैं इस विशिष्ट एक का उल्लेख कर रहा हूं), 8-बिट, शून्य मान रहा है:

0000 0000

अब 2 के पूरक प्राप्त करने के लिए सभी बिट्स को फ्लिप करें और 1 जोड़ें:

1111 1111 (flip)
0000 0001 (add one)
---------
0000 0000

हमें मिला 0000 0000, और यह -0 का प्रतिनिधित्व है।

लेकिन ध्यान दें कि 1 के पूरक में, हस्ताक्षरित 0 0000 0000 है, लेकिन -0 1111 1111 है।


1
क्या मुझे पता चल सकता है कि कृपया मेरे उत्तर को बेहतर बनाने के लिए डाउनवोट्स क्यों?
Maroun

1
जबकि अधिकांश अन्य उत्तर तकनीकी रूप से सही हैं, आपका उत्तर व्यावहारिक है, और एक कार्यान्वयन प्रदान करता है। अच्छा।
umlcat

9

मैंने इस उत्तर को छोड़ने का फैसला किया है क्योंकि सी और सी ++ कार्यान्वयन आमतौर पर निकटता से संबंधित हैं, लेकिन वास्तव में यह सी मानक के लिए स्थगित नहीं करता है जैसा कि मैंने सोचा था कि यह किया था। मुद्दा यह है कि C ++ मानक यह निर्दिष्ट नहीं करता है कि इन जैसे मामलों के लिए क्या होता है। यह भी प्रासंगिक है कि गैर-दो-पूरक प्रतिनिधित्व वास्तविक दुनिया में अत्यधिक दुर्लभ हैं, और यहां तक ​​कि जहां वे मौजूद हैं वे अक्सर इसे उजागर करने के बजाय कई मामलों में अंतर छिपाते हैं क्योंकि कोई व्यक्ति आसानी से खोज करने की उम्मीद कर सकता है।


पूर्णांक निरूपणों में ऋणात्मक शून्य का व्यवहार जिसमें वे मौजूद हैं, सी + + मानक के रूप में कड़ाई से परिभाषित नहीं है क्योंकि यह सी मानक में है। हालांकि, यह सी मानक (आईएसओ / आईईसी 9899: 1999) को शीर्ष स्तर पर एक मानक संदर्भ के रूप में उद्धृत करता है [1.2]।

सी मानक में [६.२.६.२], एक नकारात्मक शून्य केवल बिटवाइज़ ऑपरेशंस या ऑपरेशन्स का परिणाम हो सकता है, जहाँ एक नकारात्मक शून्य पहले से ही मौजूद है (उदाहरण के लिए, एक मान द्वारा ऋणात्मक शून्य को गुणा या भाग करना, या ऋणात्मक शून्य को जोड़ना शून्य) - एक शून्य शून्य मान ऑपरेटर को एक सामान्य शून्य के मूल्य पर लागू करना, जैसा कि आपके उदाहरण में, इसलिए सामान्य शून्य में परिणाम की गारंटी है।

यहां तक ​​कि उन मामलों में जो नकारात्मक शून्य उत्पन्न कर सकते हैं, इस बात की कोई गारंटी नहीं है कि वे नकारात्मक शून्य का समर्थन करने वाली प्रणाली पर भी करेंगे:

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

इसलिए, हम निष्कर्ष निकाल सकते हैं: नहीं, इस मामले का पता लगाने का कोई विश्वसनीय तरीका नहीं है। भले ही इस तथ्य के लिए नहीं कि आधुनिक कंप्यूटर सिस्टम में गैर-दो-पूरक प्रतिनिधित्व बहुत असामान्य हैं।

सी ++ मानक, इसके भाग के लिए, "नकारात्मक शून्य" शब्द का कोई उल्लेख नहीं करता है, और हस्ताक्षरित परिमाण और किसी के पूरक प्रतिनिधित्व के विवरण की बहुत कम चर्चा है, सिवाय नोट के [3.9.1 पैरा 7] कि उन्हें अनुमति है।


सामान्य तौर पर, तथ्य यह है कि C में कुछ सच है / आवश्यक है इसका मतलब यह नहीं है कि यह C ++ में सच है / आवश्यक है। तथ्य यह है कि सी एक मानक संदर्भ है इसका मतलब है कि सी ++ विभिन्न चीजों (मुख्य रूप से मानक हेडर की सामग्री) के लिए सी मानक को संदर्भित करता है, लेकिन पूर्णांक प्रकारों की परिभाषा उन चीजों में से एक नहीं है। हालांकि, एक नकारात्मक शून्य उत्पन्न करने के लिए गारंटीकृत तरीके के अभाव का अर्थ है कि आप जो निष्कर्ष निकालते हैं वह अभी भी सच है, प्रतिनिधित्व मौजूद होने पर भी अंकगणित का उपयोग करके किसी को उत्पन्न करने का कोई निश्चित तरीका नहीं है।
स्टीव जेसप

फिर सी ++ मानक इस तरह की चीजों पर इतने कम विस्तार में क्यों जाता है?
रैंडम 832

1
व्यक्तिगत स्वाद, मुझे लगता है, यदि C ++ मानक पर मतदान करने वाले लोगों की संख्या को "व्यक्तिगत" माना जा सकता है :-) यदि यह परिभाषाओं के लिए C मानक को स्थगित करने जा रहा था, तो यह इसका उचित काम कर सकता है और इसमें कोई विवरण नहीं है, जैसा कि कुछ अन्य मामलों में है।
स्टीव जेसोप

क्या "C ++ ISO / IEC 9899: 1999 प्रोग्रामिंग भाषाओं - C (बाद में C मानक के रूप में संदर्भित) में वर्णित C प्रोग्रामिंग भाषा पर आधारित एक सामान्य प्रयोजन प्रोग्रामिंग भाषा है।" [१.१ पैरा २] का कोई प्रामाणिक अर्थ है? मैंने सोचा था कि आमतौर पर सी + + मानक द्वारा ओवरराइड नहीं होने वाली किसी भी चीज के लिए सी मानक को शामिल करना था।
रैंडम 832

@ Random832 नहीं। यह सिर्फ एक ऐतिहासिक टिप्पणी (वहाँ है, उदाहरण के लिए, कोई _Boolया _Complexया नामित initializers या सी में यौगिक शाब्दिक ++)। C ++ मानक जानता है कि C मानक को कैसे शामिल किया जाए - जब वह चाहता है - जैसे, [basic.fundamental] / p3: "हस्ताक्षरित और अहस्ताक्षरित पूर्णांक प्रकार C मानक, खंड 5.2.4.2.1 में दिए गए अवरोधों को संतुष्ट करेंगे।"
TC

8

यदि आपकी मशीन के लिए अलग-अलग अभ्यावेदन हैं, -0और +0फिर memcmpउन्हें अलग कर पाएंगे।

यदि पैडिंग बिट्स मौजूद हैं, तो वास्तव में शून्य के अलावा अन्य मूल्यों के लिए कई प्रतिनिधित्व हो सकते हैं।


5

सी ++ भाषा विनिर्देश में, नकारात्मक शून्य जैसा कोई इंट नहीं है

इसका केवल यही अर्थ है कि उन दो शब्दों के लिए -लागू किया जाने वाला एकरी संचालक है 0, जैसे कि तीन प्लस पांच सिर्फ बाइनरी ऑपरेटर +है 3और जिसे लागू किया गया है 5

यदि एक अलग नकारात्मक शून्य था , तो दो का पूरक (पूर्णांक प्रकारों का सबसे सामान्य प्रतिनिधित्व) C ++ कार्यान्वयन के लिए एक अपर्याप्त प्रतिनिधित्व होगा, क्योंकि शून्य के दो रूपों का प्रतिनिधित्व करने का कोई तरीका नहीं है।


इसके विपरीत, फ्लोटिंग पॉइंट (IEEE के बाद) में अलग-अलग पॉजिटिव और नेगेटिव जीरो होते हैं। उन्हें प्रतिष्ठित किया जा सकता है, उदाहरण के लिए, जब उनके द्वारा 1 को विभाजित किया जाए। सकारात्मक शून्य सकारात्मक अनंत पैदा करता है; नकारात्मक शून्य नकारात्मक अनंत पैदा करता है।


हालाँकि, यदि इंट 0 (या किसी भी int, या किसी अन्य प्रकार के किसी भी अन्य मूल्य) के विभिन्न मेमोरी प्रतिनिधित्व होते हैं, तो आप इसका memcmpपता लगाने के लिए उपयोग कर सकते हैं :

#include <string>

int main() {
    int a = ...
    int b = ...
    if (memcmp(&a, &b, sizeof(int))) {
        // a and b have different representations in memory
    }
}

बेशक, अगर ऐसा होता है, प्रत्यक्ष स्मृति संचालन के बाहर, दोनों मान अभी भी उसी तरह से काम करेंगे।


3
दरअसल, अपने अस्तित्व को अनिवार्य नहीं करने वाली भाषा का मतलब यह नहीं है कि यह उसकी अनुपस्थिति को अनिवार्य करती है। संकेत: यह न तो अनिवार्य है।
डिडुप्लिकेटर 19

2
@ डेडप्लिकेटर, की तरह। "C ++ भाषा में", मेरा मतलब है, "C ++ भाषा विनिर्देश में "। चूँकि कल्पना में फ्रोबिनेटरों का कोई उल्लेख नहीं है, इसलिए मैं यह कह सकता था कि बहुत अधिक अस्पष्टता के बिना "सी ++ में फ्रोबिनएटर नहीं है"। मुझे लगा कि यह स्पष्ट है, लेकिन मैं इसमें सुधार करूंगा।
पॉल ड्रेपर

1
भाषा युक्ति में यूनिकॉर्न का उल्लेख नहीं है।
ypercube y

2

सरल बनाने के लिए मुझे कल्पना करना आसान लगा।

प्रकार int (_32) 32 बिट्स के साथ संग्रहीत किया जाता है । 32 बिट्स का मतलब 2 ^ 32 = 4294967296 अद्वितीय मूल्य है । इस प्रकार:

अहस्ताक्षरित int डेटा रेंज 0 से 4,294,967,295 है

नकारात्मक मूल्यों के मामले में यह इस बात पर निर्भर करता है कि उन्हें कैसे संग्रहीत किया जाता है। यदि

वन के पूरक मूल्य के मामले में -0 मौजूद है।


2
मैंने नीचा नहीं देखा intहै , लेकिन जिन प्लेटफ़ॉर्मों के लिए 32 बिट्स संग्रहीत नहीं हैं, वे अधिक लोकप्रिय हैं और आजकल के पूरक वाले प्लेटफॉर्म।
मैकीज पीचोटका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.