C # पूर्णांक अंकगणित में, a / b / c सदैव a / (b * c) के बराबर होता है?


81

चलो, बी और सी गैर-बड़े सकारात्मक पूर्णांक हैं। क्या A / b / c हमेशा C # पूर्णांक अंकगणित के साथ a (b * c) के बराबर होता है? मेरे लिए, C # में ऐसा दिखता है:

int a = 5126, b = 76, c = 14;
int x1 = a / b / c;
int x2 = a / (b * c);

तो मेरा सवाल है: x1 == x2सभी के लिए एक, बी और सी?


3
यह मैथ्स का सवाल है, प्रोग्रामिंग का नहीं। क्या आप बता सकते हैं कि इस प्रश्न का प्रोग्रामिंग विशिष्ट भाग क्या है?
Oded

38
@ किसी भी परिमेय संख्या के दायरे में, सुनिश्चित, लेकिन यह विशेष रूप से पूर्णांक अंकगणित (C # में) की बात कर रहा है। IMO जो इसे प्रोग्रामिंग से संबंधित बनाता है। हो सकता है कि नियम / a / b / c == a (b * c) पूर्णांक अंकगणित में हो, शायद यह केवल परिमेय संख्या अंकगणित में हो।
टिम एस।

43
यह C # के बारे में एक पूरी तरह से उचित प्रश्न है, और उत्तर देना आसान है।
एरिक लिपर्ट

12
@Oded यह कंप्यूटर अंकगणित के बारे में एक प्रश्न है और क्या यह शुद्ध गणित के समान है। इसे बंद नहीं किया जाना चाहिए।
जेफरी सैक्स

4
मैं क्यों (या वास्तव में चाहे) के एक गणितीय प्रमाण में दिलचस्पी लेता हूं, ओवरफ्लो को अनदेखा करते हुए, दोनों वास्तव में बराबर हैं, लेकिन मैं अभी तक एक साथ रखने में कामयाब नहीं हुआ हूं।
Rawling

जवाबों:


71

चलो \निरूपित पूर्णांक प्रभाग (सी # /दोनों के बीच ऑपरेटर intरों) दो और /निरूपित सामान्य गणित विभाजन। तो फिर, अगर x,y,zहैं धनात्मक पूर्णांक और हम कर रहे हैं अतिप्रवाह अनदेखी ,

(x \ y) \ z
    = floor(floor(x / y) / z)      [1]
    = floor((x / y) / z)           [2]
    = floor(x / (y * z))
    = x \ (y * z)

कहाँ पे

a \ b = floor(a / b)

लाइन [1]से लाइन के [2]ऊपर की छलांग को निम्नानुसार समझाया गया है। मान लीजिए कि आपके पास दो पूर्णांक aऔर सीमा में bएक भिन्नात्मक संख्या fहै [0, 1)। यह देखना सीधा है

floor(a / b) = floor((a + f) / b)  [3]

अगर लाइन में [1]आप पहचानते हैं a = floor(x / y), f = (x / y) - floor(x / y)और b = z, तो [3]इसका मतलब है कि [1]और [2]समान हैं।

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


अतिप्रवाह के मुद्दे पर - एक अच्छी व्याख्या के लिए एरिक लिपर्ट का जवाब देखें! वह अपने ब्लॉग पोस्ट और उत्तर में बहुत अधिक कठोर दृष्टिकोण अपनाता है , आपको कुछ ऐसा दिखना चाहिए जिससे आपको लगे कि मैं बहुत हैंड-वेवी हूं।


1
हाह, कि मैं क्या था के बाद :)
30'13

मुझे इसके लिए आपका \ _ और / का उपयोग पसंद है। चीजों को और अधिक स्पष्ट करता है।
जस्टिन मॉर्गन

@JustinMorgan संकेतन वास्तव में कुछ अन्य प्रोग्रामिंग भाषाओं में उपयोग किया जाता है (हालांकि मुझे याद नहीं है कि इस समय कौन से लोग हैं)।
तीमुथियुस शील्ड

1
@TimothyShields VB.net करता है।
ऐरी जिओ

मुझे लगता है कि दावा सही है, लेकिन लगता है कि आपका प्रमाण एक महत्वपूर्ण कदम है। यह संभव है कि मैंने लाइन 2 => लाइन 3 के लिए आपके औचित्य को गलत समझा। मैंने जिस तरह से व्याख्या की वह floor(x / y) - (x / y)छोटी थी और z >= 1इसलिए floorउस का लाभ लेना 0 है और हम इसे अनदेखा कर सकते हैं। यह वास्तव में पालन नहीं करता है क्योंकि यह वास्तव में एक के भीतर एक जोड़ है floor()(यानी floor(1/2)बनाम पर विचार करें floor(1/2 + 1/2))।
रोलू

77

मुझे यह सवाल इतना पसंद आया कि मैंने इसे 4 जून 2013 को अपने ब्लॉग का विषय बना लिया । महान प्रश्न के लिए धन्यवाद!


बड़े मामलों के आने से आसानी होती है। उदाहरण के लिए:

a = 1073741823; 
b = 134217727;
c = 134217727;

b * cएक नकारात्मक संख्या के लिए overflows क्योंकि ।

मैं तथ्य यह है कि में है कि बढ़ेगी अंकगणित की जाँच की , के बीच का अंतर a / (b * c)और (a / b) / cएक कार्यक्रम के बीच का अंतर हो सकता है कि काम करता है और एक प्रोग्राम है जो दुर्घटनाओं। के उत्पाद हैं bऔर cएक पूर्णांक की सीमा से overflows तो पूर्व एक जाँच संदर्भ में दुर्घटना होगा।

छोटे धनात्मक पूर्णांक के लिए, कहते हैं, छोटे से छोटे को फिट करने के लिए, पहचान को बनाए रखा जाना चाहिए।


टिमोथी शील्ड्स ने सिर्फ एक सबूत पोस्ट किया; मैं यहां एक वैकल्पिक प्रमाण प्रस्तुत करता हूं। मान लें कि सभी संख्याएँ गैर-नकारात्मक पूर्णांक हैं और कोई भी कार्य अतिप्रवाह नहीं है।

पूर्णांक विभाजन x / yमान का पता लगाता है qजैसे q * y + r == x, जहां 0 <= r < y

तो विभाजन इस तरह a / (b * c)का मान पाता q1है

q1 * b * c + r1 == a

कहाँ पे 0 <= r1 < b * c

विभाजन ( a / b ) / cपहले मान को qtऐसे पाता है

qt * b + r3 == a

और फिर q2इस तरह के मूल्य पाता है

q2 * c + r2 == qt

इतना विकल्प है कि में qtऔर हम प्राप्त:

q2 * b * c + b * r2 + r3 == a

जहां 0 <= r2 < cऔर 0 <= r3 < b

समान के बराबर दो चीजें एक दूसरे के बराबर हैं, इसलिए हमारे पास है

q1 * b * c + r1 == q2 * b * c + b * r2 + r3

q1 == q2 + xकुछ पूर्णांक के लिए मान लीजिए x। इसके लिए और इसमें हल करें x:

q2 * b * c + x * b * c + r1 = q2 * b * c + b * r2 + r3
x  = (b * r2 + r3 - r1) / (b * c)

कहाँ पे

 0 <= r1 < b * c
 0 <= r2 < c
 0 <= r3 < b

कर सकते हैं xशून्य से अधिक होना? हमारे पास असमानताएं हैं:

 b * r2 + r3 - r1 <= b * r2 + r3 <= b * (c - 1) + r3 < b * (c - 1) + b == b * c

तो उस अंश का अंश हमेशा से छोटा होता है b * c, इसलिए xशून्य से अधिक नहीं हो सकता है।

कर सकते हैं xशून्य से भी कम हो? नहीं, इसी तरह के तर्क से, पाठक पर छोड़ दिया।

इसलिए पूर्णांक xशून्य है, और इसलिए q1 == q2


7
@JoseRuiSantos हाँ, लेकिन दोनों x1 औरx2 आपरेशन उस मामले में हूबहू दुर्घटना होगा
मार्क Gravell

@JoseRuiSantos दोनों मामलों के सच नहीं है?
जोड्रेल

vc 74 का उत्तर हटा दिया गया है, इसलिए अधिकांश लोग अब आपके द्वारा संदर्भित उदाहरण नहीं देख सकते हैं।
गाबे

यह सही है, दोनों x1और x2अगर दुर्घटना होगा bया cशून्य कर रहे हैं। अन्य मूल्यों के लिए, x1अभिव्यक्ति के बाद से के संभावित पूर्णांक अतिप्रवाह से बचने जाएगा, बेहतर है ( b * c)कि x2है।
जोस रुई सैंटोस

Overflows और चेक अंकगणित के बारे में दिलचस्प बिंदु, धन्यवाद!
जेसन क्रीज

4

यदि के पूर्ण मान bऔर लगभग cनीचे हैं sqrt(2^31)(लगभग 46 300), तो यह b * cकभी भी अतिप्रवाह नहीं होगा, मान हमेशा मेल खाएंगे। यदि b * cओवरफ्लो होता है, तो एक त्रुटि को एक checkedसंदर्भ में फेंक दिया जा सकता है, या आप एक uncheckedसंदर्भ में गलत मान प्राप्त कर सकते हैं ।


2

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

चलो मान लेते हैं a/b=q1, जिसका अर्थ है a=b*q1+r1, जहां 0<=r1<b
अब मान लीजिए कि a/b/c=q2जिसका मतलब है q1=c*q2+r2, जहां 0<=r2<c
इसका मतलब है कि a=b(c*q2+r2)+r1=b*c*q2+br2+r1
आदेश में a/(b*c)=a/b/c=q2, हम करने की जरूरत है 0<=b*r2+r1<b*c
लेकिन b*r2+r1<b*r2+b=b*(r2+1)<=b*c, आवश्यकतानुसार और दो संचालन मेल खाते हैं।

यह काम नहीं करता है bया cनकारात्मक हैं, लेकिन मुझे नहीं पता कि पूर्णांक विभाजन उस स्थिति में भी कैसे काम करता है।


0

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

लक्ष्य यह दिखाना है कि

floor(floor(x/y)/z) = floor(x/y/z)

जहां /सामान्य विभाजन है (इस प्रमाण के दौरान)।

हम a/b विशिष्ट रूप से भागफल और शेष का प्रतिनिधित्व करते हैं a = kb + r(इसके द्वारा हमारा मतलब है कि k,rअद्वितीय हैं और नोट भी हैं |r| < |b|)। तो हमारे पास हैं:

(1) floor(x/y) = k => x = ky + r
(2) floor(floor(x/y)/r) = k1 => floor(x/y) = k1*z + r1
(3) floor(x/y/z) = k2 => x/y = k2*z + r2

इसलिए हमारा लक्ष्य सिर्फ यह दिखाना है k1 == k2। वैसे हमारे पास है:

k1*z + r1 = floor(x/y) = k = (x-r)/y (from lines 1 and 2)
=> x/y - r/y = k1*z + r1 => x/y = k1*z + r1 + r/y

और इस तरह:

(4) x/y = k1*z + r1 + r/y (from above)
x/y = k2*z + r2 (from line 3)

अब (2) से देखें जो r1एक पूर्णांक है ( k1*zपरिभाषा के अनुसार पूर्णांक है) और r1 < z(परिभाषा द्वारा भी)। इसके अलावा (1) हम जानते हैं कि r < y => r/y < 1। अब r1 + r/y(4) से योग पर विचार करें । दावा यह है कि r1 + r/y < zयह पिछले दावों से स्पष्ट है (क्योंकि 0 <= r1 < zऔर r1पूर्णांक है इसलिए हमारे पास है 0 <= r1 <= z-1। इसलिए 0 <= r1 + r/y < z)। इस प्रकार की r1 + r/y = r2परिभाषा के द्वारा r2(अन्यथा दो अवशेष होंगे जिनसे शेष x/yकी परिभाषा विरोधाभासी है)। इसलिए हमारे पास है:

x/y = k1*z + r2
x/y = k2*z + r2

और हमारे पास अपना वांछित निष्कर्ष है k1 = k2

उपरोक्त प्रमाण को कुछ चरणों के अलावा नकारात्मक के साथ काम करना चाहिए जिन्हें आपको एक अतिरिक्त मामले (ओं) की जांच करने की आवश्यकता होगी ... लेकिन मैंने जांच नहीं की।


0

काउंटर उदाहरण: INT_MIN / -1 / 2


"चलो, बी और सी गैर-बड़े सकारात्मक पूर्णांक हैं।"
पंग

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