मैं यह कैसे सुनिश्चित कर सकता हूं कि पूर्णांकों का एक विभाजन हमेशा गोल हो?


242

मैं यह सुनिश्चित करना चाहता हूं कि यदि आवश्यक हो तो पूर्णांकों का एक विभाजन हमेशा गोल हो। क्या इससे बेहतर कोई तरीका है? काफी कास्टिंग चल रही है। :-)

(int)Math.Ceiling((double)myInt1 / myInt2)

48
क्या आप अधिक स्पष्ट रूप से परिभाषित कर सकते हैं कि आप "बेहतर" क्या मानते हैं? और तेज? छोटा? अधिक सटीक? और अधिक मजबूत? अधिक स्पष्ट रूप से सही है?
एरिक लिपर्ट

6
आपके पास हमेशा C # में मैथ्स के साथ बहुत सारे कास्टिंग हैं - यही कारण है कि इस तरह की चीज़ के लिए यह एक महान भाषा नहीं है। क्या आप चाहते हैं कि मान शून्य से ऊपर या दूर हो - -3.1 (-3) (-4) या शून्य से दूर जाना चाहिए
कीथ

9
एरिक: आपका क्या मतलब है "अधिक सटीक? अधिक मजबूत? अधिक स्पष्ट रूप से सही?" वास्तव में मैंने जो किया उसका मतलब सिर्फ "बेहतर" था, मैं पाठक को बेहतर अर्थ देने दूंगा। तो अगर किसी के पास कोड का एक छोटा टुकड़ा था, तो महान, अगर किसी दूसरे का तेज़ था, तो भी महान :-) आपके बारे में आपके पास कोई सुझाव क्या है?
कार्स्टन

1
क्या मैं एकमात्र ऐसा व्यक्ति हूं, जिसने शीर्षक पढ़ा, हालांकि, "ओह, यह सी # के राउंडअप का कुछ प्रकार है?"
मैट बॉल

6
यह वास्तव में आश्चर्यजनक है कि यह प्रश्न कितना सूक्ष्म रूप से कठिन है, और चर्चा कितनी शिक्षाप्रद रही है।
जस्टिन मॉर्गन

जवाबों:


669

अद्यतन: यह प्रश्न जनवरी 2013 में मेरे ब्लॉग का विषय था । महान प्रश्न के लिए धन्यवाद!


पूर्णांक अंकगणितीय सही होना कठिन है। जैसा कि इस प्रकार अब तक प्रदर्शित किया गया है, जिस क्षण आप "चतुर" चाल करने की कोशिश करते हैं, संभावनाएं अच्छी होती हैं कि आपने गलती की है। और जब कोई दोष पाया जाता है, तो यह तय किए बिना कि क्या कुछ और टूट जाता है, एक अच्छी समस्या को सुलझाने की तकनीक नहीं है, इस पर विचार किए बिना दोष को ठीक करने के लिए कोड को बदलना । अब तक हमने सोचा है कि यह पूरी तरह से विशेष रूप से मुश्किल समस्या पोस्ट करने के लिए पांच अलग-अलग गलत पूर्णांक अंकगणितीय समाधान हैं।

पूर्णांक अंकगणितीय समस्याओं के दृष्टिकोण का सही तरीका - वह तरीका, जो पहली बार में उत्तर प्राप्त करने की संभावना को बढ़ाता है - समस्या को सावधानी से दृष्टिकोण करना है, इसे एक बार में एक कदम हल करें, और करने में अच्छे इंजीनियरिंग सिद्धांतों का उपयोग करें इसलिए।

जिसे आप बदलने का प्रयास कर रहे हैं, उसके लिए विनिर्देश पढ़कर शुरू करें। पूर्णांक विभाजन के लिए विनिर्देश स्पष्ट रूप से बताता है:

  1. विभाजन परिणाम को शून्य की ओर ले जाता है

  2. परिणाम शून्य या सकारात्मक होता है जब दो ऑपरेंड के समान संकेत और शून्य या नकारात्मक होते हैं जब दोनों ऑपरेंड के विपरीत संकेत होते हैं

  3. यदि बाएं ऑपरेंड सबसे छोटा प्रतिनिधित्व योग्य इंट और राइट ऑपरैंड -1 है, तो एक अतिप्रवाह होता है। [...] यह कार्यान्वयन के रूप में परिभाषित किया जाता है कि क्या [एक अंकगणित अपवाद] फेंक दिया जाता है या ओवरफ्लो चला जाता है जिसके परिणामस्वरूप मूल्य बाएं ऑपरेंड के समान होता है।

  4. यदि सही ऑपरेंड का मान शून्य है, तो System.DivideByZeroException को फेंक दिया जाता है।

हम जो चाहते हैं वह पूर्णांक विभाजन फ़ंक्शन है जो भागफल की गणना करता है लेकिन परिणाम हमेशा ऊपर की ओर होता है , हमेशा शून्य की ओर नहीं ।

इसलिए उस फ़ंक्शन के लिए एक विनिर्देश लिखें। हमारे कार्य में int DivRoundUp(int dividend, int divisor)हर संभव इनपुट के लिए परिभाषित व्यवहार होना चाहिए। यह अपरिभाषित व्यवहार गहरी चिंताजनक है, तो चलिए इसे खत्म करते हैं। हम कहेंगे कि हमारे ऑपरेशन में यह विनिर्देश है:

  1. यदि विभाजक शून्य है तो ऑपरेशन फेंकता है

  2. यदि लाभांश int.minval है और भाजक -1 है, तो ऑपरेशन फेंकता है

  3. यदि कोई शेष नहीं है - विभाजन 'सम' है - तो वापसी मूल्य अभिन्न भागफल है

  4. अन्यथा यह सबसे छोटा पूर्णांक देता है जो भागफल से अधिक होता है, अर्थात यह हमेशा गोल होता है।

अब हमारे पास एक विनिर्देश है, इसलिए हम जानते हैं कि हम एक परीक्षण योग्य डिजाइन के साथ आ सकते हैं । मान लें कि हम एक अतिरिक्त डिजाइन मानदंड जोड़ते हैं कि समस्या को पूर्णांक अंकगणित के साथ हल किया जा सकता है, बल्कि भागफल को दोहरे के रूप में गणना करने के बजाय, क्योंकि समस्या कथन में "डबल" समाधान स्पष्ट रूप से अस्वीकार कर दिया गया है।

तो हमें क्या गणना करनी चाहिए? स्पष्ट रूप से, पूर्णांक अंकगणित में पूरी तरह से शेष रहते हुए हमारी कल्पना को पूरा करने के लिए, हमें तीन तथ्यों को जानना होगा। सबसे पहले, पूर्णांक भागफल क्या था? दूसरा, क्या विभाजन शेष था? और तीसरा, यदि नहीं, तो पूर्णांक को ऊपर या नीचे गोल करके गणना की गई थी?

अब जब हमारे पास एक विनिर्देश और एक डिज़ाइन है, तो हम कोड लिखना शुरू कर सकते हैं।

public static int DivRoundUp(int dividend, int divisor)
{
  if (divisor == 0 ) throw ...
  if (divisor == -1 && dividend == Int32.MinValue) throw ...
  int roundedTowardsZeroQuotient = dividend / divisor;
  bool dividedEvenly = (dividend % divisor) == 0;
  if (dividedEvenly) 
    return roundedTowardsZeroQuotient;

  // At this point we know that divisor was not zero 
  // (because we would have thrown) and we know that 
  // dividend was not zero (because there would have been no remainder)
  // Therefore both are non-zero.  Either they are of the same sign, 
  // or opposite signs. If they're of opposite sign then we rounded 
  // UP towards zero so we're done. If they're of the same sign then 
  // we rounded DOWN towards zero, so we need to add one.

  bool wasRoundedDown = ((divisor > 0) == (dividend > 0));
  if (wasRoundedDown) 
    return roundedTowardsZeroQuotient + 1;
  else
    return roundedTowardsZeroQuotient;
}

क्या यह चतुर है? कोई सुंदर नहीं? नहीं लघु? विनिर्देश के अनुसार सही नहीं है? मैं ऐसा मानता हूं, लेकिन मैंने इसका पूरी तरह से परीक्षण नहीं किया है। हालांकि यह बहुत अच्छा लग रहा है।

हम यहाँ पेशेवर हैं; अच्छी इंजीनियरिंग प्रथाओं का उपयोग करें। अपने टूल पर शोध करें, वांछित व्यवहार निर्दिष्ट करें, पहले त्रुटि के मामलों पर विचार करें, और इसकी स्पष्ट शुद्धता पर जोर देने के लिए कोड लिखें। और जब आप एक बग ढूंढते हैं, तो विचार करें कि क्या आपका एल्गोरिदम आपके साथ शुरू होने से पहले ही बेतरतीब ढंग से तुलना करना शुरू कर देता है, ताकि तुलनात्मक रूप से चारों ओर की दिशाओं की अदला-बदली शुरू हो जाए और जो सामान पहले से काम करता है उसे तोड़ दें।


44
उत्कृष्ट अनुकरणीय उत्तर
गेविन मिलर

61
जिस चीज की मुझे परवाह है, वह व्यवहार नहीं है; या तो व्यवहार उचित लगता है। मुझे इसकी परवाह है कि यह निर्दिष्ट नहीं है , जिसका अर्थ है कि यह आसानी से परीक्षण नहीं किया जा सकता है। इस मामले में, हम अपने स्वयं के ऑपरेटर को परिभाषित कर रहे हैं, इसलिए हम जो भी व्यवहार पसंद करते हैं उसे निर्दिष्ट कर सकते हैं। मुझे परवाह नहीं है कि क्या व्यवहार "फेंक" या "फेंक नहीं" है, लेकिन मुझे परवाह है कि यह कहा गया है।
एरिक लिपर्ट

68
डरने की बात है, पैदल सेना विफल :(
जॉन स्कीट

32
आदमी - क्या तुम उस पर एक किताब लिख सकते हो?
xtofl

76
@finnw: क्या मैंने इसका परीक्षण किया है या नहीं यह अप्रासंगिक है। इस पूर्णांक अंकगणितीय समस्या को हल करना मेरी व्यावसायिक समस्या नहीं है; अगर ऐसा होता, तो मैं इसका परीक्षण करता। किसी को अपने व्यवसाय समस्या को हल करने इंटरनेट बंद अजनबियों से कोड ले जाना चाहता है तो जिम्मेदारी पर है उन्हें अच्छी तरह से यह परीक्षण करने के लिए।
एरिक लिपर्ट

49

यहाँ अब तक के सभी उत्तर अधिक जटिल प्रतीत होते हैं।

सकारात्मक लाभांश और भाजक के लिए C # और Java में, आपको बस करने की आवश्यकता है:

( dividend + divisor - 1 ) / divisor 

स्रोत: नंबर रूपांतरण, रोलैंड बैकहाउस, 2001


बहुत बढ़िया। हालाँकि, आपको कोष्ठक को हटाने के लिए कोष्ठक जोड़ना चाहिए। इसके लिए प्रमाण थोड़ा लंबा था, लेकिन आप इसे आंत में महसूस कर सकते हैं कि यह सही है, बस इसे देखकर।
जर्गेन सिगवार्डसन

1
हम्म ... डिविडेंड = 4, डिवाइज़र = (- 2) के बारे में क्या ??? 4 / (-2) = (-2) = (-2) गोल होने के बाद। लेकिन आपके द्वारा प्रदान किया गया एल्गोरिथम (4 + (-2) - 1) / (-2) = 1 / (-2) = (-0.5) = 0 गोल होने के बाद।
स्कॉट

1
@ सच - क्षमा करें, मैं यह उल्लेख करने के लिए बच गया कि यह समाधान केवल सकारात्मक लाभांश और भाजक के लिए है। मैंने स्पष्ट करने के लिए अपने उत्तर को अपडेट कर दिया है।
इयान नेल्सन

1
मुझे यह पसंद है, निश्चित रूप से आप अंश में कुछ कृत्रिम अतिप्रवाह कर सकते हैं इस दृष्टिकोण के एक उपोत्पाद के रूप में ...
TCC

2
@PIntag: विचार अच्छा है, लेकिन मोडुलो का उपयोग गलत है। 13 और 3. परिणाम 5 की अपेक्षा करें, लेकिन ((13-1)%3)+1)परिणाम के रूप में 1 देता है। सही प्रकार के विभाजन को लेना, 1+(dividend - 1)/divisorसकारात्मक लाभांश और भाजक के उत्तर के समान परिणाम देता है। इसके अलावा, कोई अतिप्रवाह समस्या नहीं है, हालांकि वे कृत्रिम हो सकते हैं।
लुत्ज़ लेहमन

48

अंतिम अंतर-आधारित उत्तर

हस्ताक्षरित पूर्णांकों के लिए:

int div = a / b;
if (((a ^ b) >= 0) && (a % b != 0))
    div++;

अहस्ताक्षरित पूर्णांक के लिए:

int div = a / b;
if (a % b != 0)
    div++;

इस जवाब के लिए तर्क

पूर्णांक विभाजन ' /' को शून्य की ओर गोल करने के लिए परिभाषित किया गया है (कल्पना का 7.7.2), लेकिन हम गोल करना चाहते हैं। इसका मतलब है कि नकारात्मक उत्तर पहले से ही सही ढंग से गोल हैं, लेकिन सकारात्मक उत्तरों को समायोजित करने की आवश्यकता है।

गैर-शून्य सकारात्मक जवाबों का पता लगाना आसान है, लेकिन उत्तर शून्य थोड़ा पेचीदा है, क्योंकि यह या तो नकारात्मक मान के चक्कर में पड़ सकता है या सकारात्मक के नीचे चक्कर लगा सकता है।

सबसे सुरक्षित शर्त यह पता लगाना है कि जब उत्तर यह जाँच कर सकारात्मक होना चाहिए कि दोनों पूर्णांक समान हैं। पूर्णांक एक्सोर ऑपरेटर '^दो मूल्यों पर ' का परिणाम होगा 0 साइन-बिट जब यह मामला होता है, जिसका अर्थ है एक गैर-नकारात्मक परिणाम, इसलिए चेक (a ^ b) >= 0यह निर्धारित करता है कि परिणाम गोल होने से पहले सकारात्मक होना चाहिए था। यह भी ध्यान दें कि अहस्ताक्षरित पूर्णांकों के लिए, प्रत्येक उत्तर स्पष्ट रूप से सकारात्मक है, इसलिए इस चेक को छोड़ा जा सकता है।

एक ही जाँच शेष है कि क्या कोई राउंडिंग हुई है, जिसके लिए a % b != 0 लिए वह काम करेगा।

सीख सीखी

अंकगणित (पूर्णांक या अन्यथा) लगभग उतना सरल नहीं है जितना लगता है। हर समय ध्यान से सोचने की आवश्यकता है।

इसके अलावा, हालांकि मेरा अंतिम उत्तर शायद 'सरल' या 'स्पष्ट' या शायद 'तेज' के रूप में फ्लोटिंग पॉइंट उत्तरों के रूप में नहीं है, लेकिन यह मेरे लिए एक बहुत मजबूत रिडीमिंग क्वालिटी है; मैंने अब उत्तर के माध्यम से तर्क दिया है, इसलिए मैं वास्तव में निश्चित हूं कि यह सही है (जब तक कि कोई मुझे अन्यथा न बताए - एरिक के निर्देश में आकर्षक नज़र -)।

फ़्लोटिंग पॉइंट उत्तर के बारे में निश्चितता की समान भावना प्राप्त करने के लिए, मुझे इस बारे में अधिक (और संभवतः अधिक जटिल) सोचना होगा कि क्या कोई ऐसी स्थिति है जिसके तहत फ़्लोटिंग पॉइंट सटीक तरीके से मिल सकता है, और क्या Math.Ceilingशायद करता है 'सिर्फ सही' इनपुट पर कुछ अवांछनीय।

रास्ता तय किया

बदलें (ध्यान दें मैं दूसरे की जगह myInt1के साथ myInt2, यह सोचते हैं कि आप क्या मतलब था):

(int)Math.Ceiling((double)myInt1 / myInt2)

साथ में:

(myInt1 - 1 + myInt2) / myInt2

एकमात्र चेतावनी यह है कि यदि myInt1 - 1 + myInt2आप जिस पूर्णांक प्रकार का उपयोग कर रहे हैं, उससे अधिक हो जाता है, तो आपको वह नहीं मिल सकता है जिसकी आप अपेक्षा करते हैं।

कारण यह गलत है : -1000000 और 3999 में -250 देना चाहिए, यह -249 देता है

संपादित करें: इसे
ध्यान में रखते हुए नकारात्मक myInt1मानों के लिए अन्य पूर्णांक समाधान के समान त्रुटि है , कुछ ऐसा करना आसान हो सकता है:

int rem;
int div = Math.DivRem(myInt1, myInt2, out rem);
if (rem > 0)
  div++;

divकेवल पूर्णांक संचालन का उपयोग करने में सही परिणाम देना चाहिए ।

कारण यह गलत है : -1 और -5 को 1 देना चाहिए, यह 0 देता है

EDIT (एक बार और, भावना के साथ):
डिवीजन ऑपरेटर शून्य की ओर चक्कर लगाता है; नकारात्मक परिणामों के लिए यह बिल्कुल सही है, इसलिए केवल गैर-नकारात्मक परिणामों के समायोजन की आवश्यकता है। यह भी ध्यान में रखते हुए कि DivRemबस /और %वैसे भी, चलो कॉल को छोड़ दें (और जब यह आवश्यक न हो तो modulo गणना से बचने के लिए आसान तुलना के साथ शुरू करें):

int div = myInt1 / myInt2;
if ((div >= 0) && (myInt1 % myInt2 != 0))
    div++;

कारण यह गलत है : -1 और 5 को 0 देना चाहिए, यह 1 देता है

(अंतिम प्रयास के अपने बचाव में मुझे कभी भी तर्कपूर्ण उत्तर का प्रयास नहीं करना चाहिए था जबकि मेरा दिमाग मुझे बता रहा था कि मुझे प्रति घंटे 2 घंटे हैं)


19

एक्सटेंशन विधि का उपयोग करने का सही मौका:

public static class Int32Methods
{
    public static int DivideByAndRoundUp(this int number, int divideBy)
    {                        
        return (int)Math.Ceiling((float)number / (float)divideBy);
    }
}

इससे आपका कोड uber पढ़ने योग्य भी हो जाता है:

int result = myInt.DivideByAndRoundUp(4);

1
एर्म, क्या? आपका कोड myInt.DivideByAndRoundUp () कहलाएगा और हमेशा 0 के इनपुट के अलावा 1 लौटाएगा, जो एक अपवाद का कारण बनेगा ...
विन्यासकर्ता

5
बड़ी विफलता। (-2) .DivideByAndRoundUp (2) 0. रिटर्न
Timwi

3
मैं पार्टी के लिए वास्तव में देर हो चुकी हूं, लेकिन क्या यह कोड संकलित है? मेरे गणित वर्ग में एक सीलिंग पद्धति नहीं है जो दो तर्क लेती है।
आर। मार्टिनो फर्नांडीस

17

आप एक सहायक लिख सकते हैं।

static int DivideRoundUp(int p1, int p2) {
  return (int)Math.Ceiling((double)p1 / p2);
}

1
फिर भी कास्टिंग हालांकि पर जाने की एक ही राशि
ChrisF

29
@Outlaw, आप चाहते हैं सब मान लिया। लेकिन मेरे लिए अगर वे इसे सवाल में नहीं डालते हैं, तो मैं आमतौर पर मान लेता हूं कि वे इस पर विचार नहीं करते थे।
JaredPar

1
एक सहायक लिखना बेकार है अगर यह सिर्फ इतना है। इसके बजाय, एक व्यापक परीक्षण सूट के साथ एक सहायक लिखें।
dolmen

3
@ डोलमेन क्या आप कोड के पुन: उपयोग की अवधारणा से परिचित हैं ? ऊ
रुशियो

4

आप निम्नलिखित की तरह कुछ का उपयोग कर सकते हैं।

a / b + ((Math.Sign(a) * Math.Sign(b) > 0) && (a % b != 0)) ? 1 : 0)

12
यह कोड स्पष्ट रूप से दो तरह से गलत है। सबसे पहले, सिंटैक्स में एक छोटी सी त्रुटि है; आपको अधिक कोष्ठक की आवश्यकता है। लेकिन इससे भी महत्वपूर्ण बात यह है कि यह वांछित परिणाम की गणना नहीं करता है। उदाहरण के लिए, = -1000000 और b = 3999 के साथ परीक्षण का प्रयास करें। नियमित पूर्णांक विभाजन परिणाम -250 है। डबल डिवीजन -250.0625 है ... वांछित व्यवहार को गोल करना है। स्पष्ट रूप से -250.0625 से सही राउंडिंग -250 तक राउंड करना है, लेकिन आपका कोड -249 तक राउंड है।
एरिक लिपर्ट

36
मुझे यह कहते हुए खेद है कि आपका कोड स्टिल गलत डैनियल है। १/२ को यूपी को १ राउंड करना चाहिए, लेकिन आपका कोड इसे ०.१ पर राउंड करता है। हर बार जब मैं एक बग ढूंढता हूं तो आप इसे दूसरे बग से जोड़कर "ठीक" कर लेते हैं। मेरी सलाह: ऐसा करना बंद करो। जब कोई आपके कोड में बग ढूंढता है, तो बिना सोचे समझे एक साथ एक थप्पड़ न लगाएं, जिससे पहली बार में बग का कारण बने। अच्छी इंजीनियरिंग प्रथाओं का उपयोग करें; एल्गोरिथ्म में दोष खोजने और इसे ठीक करें। आपके एल्गोरिथ्म के सभी तीन गलत संस्करणों में दोष यह है कि आप सही ढंग से यह निर्धारित नहीं कर रहे हैं कि गोलाई "नीचे" कब थी।
एरिक लिपर्ट

8
अविश्वसनीय इस कोड के छोटे टुकड़े में कितने कीड़े हो सकते हैं। मेरे पास इसके बारे में सोचने का अधिक समय नहीं था - परिणाम टिप्पणियों में प्रकट होता है। (1) एक * b> 0 सही होगा यदि यह अतिप्रवाह नहीं हुआ। A और b के चिह्न के लिए 9 संयोजन हैं - [-1, 0, +1] x [-1, 0, +1]। हम 6 मामलों [-1, 0, +1] x [-1, +1] को छोड़ कर b == 0 मामले को अनदेखा कर सकते हैं। शून्य की ओर ए / बी राउंड, जो नकारात्मक परिणामों के लिए गोल हो रहा है और पॉज़िटिव रेसुल्स के लिए नीचे चक्कर लगा रहा है। इसलिए समायोजन का प्रदर्शन किया जाना चाहिए यदि ए और बी में एक ही संकेत है और दोनों शून्य नहीं हैं।
डैनियल ब्रुकनर

5
यह उत्तर शायद सबसे खराब चीज है जो मैंने एसओ पर लिखी है ... और यह अब एरिक के ब्लॉग से जुड़ा हुआ है ... खैर, मेरा इरादा एक पठनीय समाधान देने का नहीं था; मैं वास्तव में एक छोटी और तेज हैक के लिए लॉक कर रहा था। और अपने समाधान का फिर से बचाव करने के लिए, मुझे पहली बार सही विचार आया, लेकिन ओवरफ्लो के बारे में नहीं सोचा। यह स्पष्ट रूप से मेरी गलती थी कि कोड को बिना पोस्ट किए और विज़ुअलस्टडियो में परीक्षण किए बिना। "सुधार" और भी बदतर हैं - मुझे महसूस नहीं हुआ कि यह एक अतिप्रवाह समस्या थी और मुझे लगा कि मैंने एक तार्किक गलती की है। परिणाम में पहले "सुधार" कुछ भी नहीं बदला; मैं तो बस उलटा
डैनियल Brückner

10
तर्क और बग को चारों ओर धकेल दिया। यहाँ मैंने अगली गलतियाँ कीं; जैसा कि एरिक ने पहले ही उल्लेख किया है कि मैंने वास्तव में बग का विश्लेषण नहीं किया है और सिर्फ पहली चीज है जो सही लगती है। और मैंने अभी भी VisualStudio का उपयोग नहीं किया। ठीक है, मैं जल्दी में था और "फिक्स" पर पांच मिनट से ज्यादा नहीं बिताया, लेकिन यह कोई बहाना नहीं होना चाहिए। एरिक के बार-बार बग को इंगित करने के बाद, मैंने VisualStudio को निकाल दिया और वास्तविक समस्या पाई। साइन () का उपयोग करके फिक्स चीज को और भी अधिक अपठनीय बनाता है और इसे कोड में बदल देता है जिसे आप वास्तव में बनाए नहीं रखना चाहते हैं। मैं अपने सबक सीखा है और अब काम नहीं बहुत मूल्यवान समझना कैसे मुश्किल
डैनियल Brückner

-2

ऊपर दिए गए कुछ उत्तर फ़्लोट का उपयोग करते हैं, यह अक्षम है और वास्तव में आवश्यक नहीं है। अहस्ताक्षरित ints के लिए यह int1 / int2 के लिए एक कुशल उत्तर है:

(int1 == 0) ? 0 : (int1 - 1) / int2 + 1;

साइन की हुई इन्ट्स के लिए यह सही नहीं होगा


ऐसा नहीं है कि ओपी ने पहले स्थान पर क्या पूछा, वास्तव में अन्य उत्तरों में नहीं जोड़ा जाता है।
संतमन्नो

-4

यहां सभी समाधानों के साथ समस्या यह है कि उन्हें एक कास्ट की आवश्यकता है या उन्हें एक संख्यात्मक समस्या है। फ्लोटिंग या डबल करने के लिए कास्टिंग हमेशा एक विकल्प होता है, लेकिन हम बेहतर कर सकते हैं।

जब आप @jerryjvl से उत्तर के कोड का उपयोग करते हैं

int div = myInt1 / myInt2;
if ((div >= 0) && (myInt1 % myInt2 != 0))
    div++;

एक राउंडिंग त्रुटि है। 1/5 गोल होगा, क्योंकि 1% 5! = 0. लेकिन यह गलत है, क्योंकि गोलाई केवल तब होगी जब आप 1 को 3 के साथ प्रतिस्थापित करते हैं, इसलिए परिणाम 0.6 है। हमें राउंड अप करने का एक तरीका खोजने की आवश्यकता है जब गणना हमें 0.5 से अधिक या उसके बराबर मूल्य दे। ऊपरी उदाहरण में मोडुलो ऑपरेटर के परिणाम में 0 से myInt2-1 तक की सीमा होती है। राउंडिंग तभी होगी जब शेष बंटवारे के 50% से अधिक हो। तो समायोजित कोड इस तरह दिखता है:

int div = myInt1 / myInt2;
if (myInt1 % myInt2 >= myInt2 / 2)
    div++;

निश्चित रूप से हमारे पास myInt2 / 2 में भी एक राउंडिंग समस्या है, लेकिन यह परिणाम आपको इस साइट पर अन्य लोगों की तुलना में बेहतर राउंडिंग समाधान देगा।


"हमें राउंड अप करने का एक तरीका खोजने की आवश्यकता है जब गणना हमें 0.5 से अधिक या उसके बराबर मान देती है" - आपने इस प्रश्न के बिंदु को याद किया है - या हमेशा गोल करें अर्थात ओपी 0.001 से 1 तक गोल करना चाहता है।
ग्राम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.