Java ने Math.ceil का उपयोग करते हुए एक इंट को राउंडिंग किया


101
int total = (int) Math.ceil(157/32);

यह अभी भी 4 क्यों लौटाता है? 157/32 = 4.90625, मुझे चक्कर लगाने की जरूरत है, मैंने चारों ओर देखा है और यह सही तरीका है।

मैंने टाइप के totalरूप में कोशिश की double, लेकिन 4.0 प्राप्त करें।

मैं क्या गलत कर रहा हूं?

जवाबों:


187

आप कर रहे हैं 157/32जो दो पूर्णांकों को एक दूसरे के साथ विभाजित कर रहा है, जिसके परिणामस्वरूप हमेशा पूर्णांक नीचे गोल होता है। इसलिए (int) Math.ceil(...)कुछ भी नहीं कर रहा है। आप जो चाहते हैं उसे प्राप्त करने के लिए तीन संभावित उपाय हैं। मैं विकल्प 1 या विकल्प 2 का उपयोग करने की सलाह देता हूं । कृपया विकल्प 0 का उपयोग करें ।

## विकल्प 0

कन्वर्ट aऔर bएक डबल करने के लिए, और आप विभाजन का उपयोग कर सकते हैं और Math.ceilजैसा कि आप इसे काम करना चाहते थे। हालांकि मैं इस दृष्टिकोण के उपयोग को दृढ़ता से हतोत्साहित करता हूं, क्योंकि दोहरे विभाजन को लागू किया जा सकता है। युगल के दबदबे के बारे में अधिक पढ़ने के लिए यह प्रश्न देखें ।

int n = (int) Math.ceil((double) a / b));

##विकल्प 1

int n = a / b + ((a % b == 0) ? 0 : 1); 

आप a / bहमेशा फर्श के साथ करते हैं अगर aऔर bदोनों पूर्णांक हैं। फिर आपके पास एक इनलाइन है यदि स्टेटमेंट चुड़ैल जाँचती है कि आपको फर्श के बजाय छत पर जाना चाहिए या नहीं। तो +1 या +0, यदि विभाजन के साथ शेष है तो आपको +1 की आवश्यकता होगी। a % b == 0शेष के लिए जाँच करता है।

##विकल्प 2

यह विकल्प बहुत कम है, लेकिन शायद कुछ कम सहज ज्ञान के लिए। मुझे लगता है कि यह कम सहज दृष्टिकोण दोहरे विभाजन और तुलनात्मक दृष्टिकोण से तेज होगा:
कृपया ध्यान दें कि यह काम नहीं करता है b < 0

int n = (a + b - 1) / b;

अतिप्रवाह की संभावना को कम करने के लिए आप निम्नलिखित का उपयोग कर सकते हैं। हालाँकि कृपया ध्यान दें कि यह a = 0और के लिए काम नहीं करता है b < 1

int n = (a - 1) / b + 1;

## "कम सहज दृष्टिकोण" के पीछे स्पष्टीकरण

जावा (और अधिकांश अन्य प्रोग्रामिंग भाषाओं) में दो पूर्णांक को विभाजित करने के बाद से परिणाम हमेशा सामने आएगा। इसलिए:

int a, b;
int result = a/b (is the same as floor(a/b) )

लेकिन हम विकिपीडिया से परिभाषाओं और भूखंडों का उपयोग नहीं करना चाहते floor(a/b), लेकिन :ceil(a/b)यहां छवि विवरण दर्ज करें

मंजिल और छत समारोह के इन भूखंडों के साथ आप संबंध देख सकते हैं।

मंजिल समारोह छत समारोह

आप वह देख सकते हैं floor(x) <= ceil(x)। हमें चाहिए floor(x + s) = ceil(x)। इसलिए हमें खोजने की जरूरत है s। अगर हम लेते हैं तो 1/2 <= s < 1यह सही होगा (कुछ संख्याओं को आज़माएँ और आप देखेंगे कि यह ऐसा करता है, मुझे यह साबित करने के लिए खुद को कठिन लगता है)। और 1/2 <= (b-1) / b < 1, इसलिए

ceil(a/b) = floor(a/b + s)
          = floor(a/b + (b-1)/b)
          = floor( (a+b-1)/b) )

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


1
यदि आप कम सहज दृष्टिकोण के पीछे अंतर्ज्ञान की व्याख्या कर सकते हैं तो यह एक बहुत बड़ा उपकार होगा? मुझे पता है कि यह सही है, मैं जानना चाहता हूं कि आपको यह कैसे मिला, और मैं गणितीय रूप से कैसे दिखा सकता हूं कि यह सही है। मैंने इसे गणितीय रूप से हल करने की कोशिश की, आश्वस्त नहीं था।
साद रहमान शाह

मुझे आशा है कि आप मेरे संपादन से संतुष्ट हैं, मैं ऐसा कोई भी बेहतर काम नहीं कर सकता जो मुझे लगता है :(
martijnn2008

मुझे लगता है कि Math.floor और छत केवल पूर्णांक विभाजन के लिए ही सही हैं जब लंबे समय तक विभाजन नहीं होता है जब मान डबल्स में डाले जाते हैं। काउंटर उदाहरण 4611686018427386880/4611686018427387137 फर्श पर विफल रहता है और 4611686018427386881/4611686018427386880 प्लस्तर लगाना पर विफल रहता हैं
Wouter

2
स्पष्टीकरण का एक बिंदु: विकल्प 2 के दो उप-विकल्प के परिणाम सभी मामलों में समान नहीं हैं। एक वसीयत के लिए शून्य का मान पहले में 0 और दूसरे में 1 प्रदान करेगा (जो कि अधिकांश अनुप्रयोगों के लिए सही उत्तर नहीं है)।
Sushisource

1
क्या आप वाकई मतलब "हालांकि कृपया ध्यान दें कि यह एक = 0 और ख लिए काम नहीं करता नहीं किया हैं < 1"
dantiston

60

157/32 है int/int, जिसके परिणामस्वरूप ए int

डबल शाब्दिक का उपयोग करने का प्रयास करें - 157/32d, जो है int/double, जिसके परिणामस्वरूप ए double


क्या आपको यकीन है कि int / int हमेशा एक int में परिणाम देगा ?! क्या आप कृपया उसे स्रोत दे सकते हैं ?!


34

157/32एक पूर्णांक विभाजन है क्योंकि सभी संख्यात्मक शाब्दिक पूर्णांक हैं जब तक कि एक प्रत्यय के साथ निर्दिष्ट नहीं किया जाता है ( लंबे समय के dलिए दोगुना l)

विभाजन को नीचे (4 से) गोल किया जाता है, इससे पहले कि यह एक डबल (4.0) में परिवर्तित हो जाए जो बाद में गोल (4.0) हो जाता है

यदि आप एक चर का उपयोग करते हैं तो आप इससे बच सकते हैं

double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);


7

किसी ने भी सबसे सहज का उल्लेख नहीं किया है:

int x = (int) Math.round(Math.ceil((double) 157 / 32));

यह घोल डबल डिविजन इंप्रेशन को ठीक करता है ।



धन्यवाद @ZulqurnainJutt, ने एक कलाकार को जोड़ा
IG Pascual


3

दो पूर्णांकों को विभाजित करते समय, जैसे,

int c = (int) a / (int) b;

परिणाम एक है int, जिसका मूल्य शून्य से गोल aकरके विभाजित है b। क्योंकि परिणाम पहले से ही गोल है, ceil()कुछ भी नहीं करता है। ध्यान दें कि यह गोलाई समान नहीं है floor(), जो नकारात्मक अनंत की ओर घूमती है। तो, 3/2बराबर 1(और floor(1.5)बराबर 1.0, लेकिन (-3)/2बराबर -1(लेकिन floor(-1.5)बराबर -2.0)।

यह महत्वपूर्ण है क्योंकि अगर a/bहमेशा की तरह ही थे floor(a / (double) b), तो आप बस ceil()के a/bरूप में लागू कर सकते हैं -( (-a) / b)

होने का सुझाव ceil(a/b)से

int n = (a + b - 1) / b;, जो के बराबर है a / b + (b - 1) / b, या(a - 1) / b + 1

काम करता है क्योंकि ceil(a/b)हमेशा एक से अधिक है floor(a/b), सिवाय जब a/bएक पूरी संख्या है। इसलिए, आप इसे अगले पूरे नंबर पर (या पिछले) पर टक्कर देना चाहते हैं, जब तक a/bकि पूरी संख्या न हो। जोड़ना 1 - 1 / bयह कर देगा। संपूर्ण संख्याओं के लिए, यह उन्हें अगली पूरी संख्या तक नहीं पहुंचाएगा। बाकी सब कुछ के लिए, यह होगा।

ओह। उम्मीद है कि समझ में आता है। मुझे यकीन है कि इसे समझाने के लिए एक और अधिक गणितीय तरीका है।


2

किसी संख्या को पूर्णांक से वास्तविक संख्या में बदलने के लिए आप एक बिंदु जोड़ सकते हैं:

int total = (int) Math.ceil(157/32.);

और (157/32।) का परिणाम भी वास्तविक होगा। ;)



1

अपने प्रश्न के लिए नीचे दिए गए समाधान की जाँच करें:

int total = (int) Math.ceil(157/32);

यहां आपको 1.0 के साथ न्यूमेरियर को गुणा करना चाहिए, फिर यह आपका उत्तर देगा।

int total = (int) Math.ceil(157*1.0/32);

0

जैसे कास्ट करने के लिए डबल का उपयोग करें

Math.ceil((double)value) या पसंद है

Math.ceil((double)value1/(double)value2);

0

जावा /डिफ़ॉल्ट रूप से केवल फ्लोर डिवीजन प्रदान करता है । लेकिन हम फर्श के संदर्भ में छत लिख सकते हैं । चलो देखते हैं:

yफॉर्म के साथ कोई भी पूर्णांक लिखा जा सकता है y == q*k+r। फर्श विभाजन की परिभाषा के अनुसार (यहां floor) जो गोल होता है r,

floor(q*k+r, k) == q  , where 0  r  k-1

और सीलिंग डिवीजन (यहां ceil) जो गोल है r₁,

ceil(q*k+r₁, k) == q+1  , where 1  r  k

जहां हम स्थानापन्न कर सकते हैं r+1के लिए r₁:

ceil(q*k+r+1, k) == q+1  , where 0  r  k-1


फिर हम तीसरे में पहले समीकरण स्थानापन्न के लिए qहो रही है

ceil(q*k+r+1, k) == floor(q*k+r, k) + 1  , where 0  r  k-1

अंत में, किसी भी पूर्णांक दिया yजहां y = q*k+r+1कुछ के लिए q, k, r, हमारे पास है

ceil(y, k) == floor(y-1, k) + 1

और हम कर रहे हैं। उम्मीद है की यह मदद करेगा।


मुझे यकीन है कि यह सही है, लेकिन चूंकि इस बिंदु को स्पष्ट करना है, इसलिए ceilयह मेरे लिए स्पष्ट नहीं है कि इस तरह की अंतरंग परिभाषा से क्यों परिभाषित किया गया है, विशेष रूप से जहां हम एक पूर्णांक की छत ले रहे हैं, अर्थात r1 = k। चूंकि किनारे के मामले इस बारे में मुश्किल हैं, इसलिए मुझे लगता है कि इसे थोड़ा और समझने की जरूरत है।
लुइगी प्लिंज

@LuigiPlinge मेरे लिए व्युत्पन्न विभाजन ऑपरेशन के संदर्भ में फर्श और छत के आंतरिक अंतर के कारण सरल नहीं हो सकता है। मुझे लगता है कि आपको किनारे के मामले पर ध्यान केंद्रित करने की आवश्यकता नहीं है - यह एक प्राकृतिक तथ्य है जब आप एक पूर्णांक को तोड़कर फर्श और छत की परिभाषाओं को एकजुट करने का प्रयास करते हैं। नतीजतन, सबूत सिर्फ तीन चरण हैं, और निष्कर्ष को मोटे तौर पर "एक परिशोधित कदम वापस, फिर एक निरपेक्ष कदम आगे" के रूप में याद किया जा सकता है।
शेलयली

0

ऐसी दो विधियाँ हैं जिनके द्वारा आप अपने दोहरे मान को बढ़ा सकते हैं।

  1. Math.ceil
  2. Math.floor

यदि आप अपना उत्तर 4.90625 4 के रूप में चाहते हैं, तो आपको Math.floor का उपयोग करना चाहिए और यदि आप अपना उत्तर 4.90625 5 के रूप में चाहते हैं, तो आप Math.ceil का उपयोग कर सकते हैं

आप उसके लिए निम्न कोड का उल्लेख कर सकते हैं।

public class TestClass {

    public static void main(String[] args) {
        int floorValue = (int) Math.floor((double)157 / 32);
        int ceilValue = (int) Math.ceil((double)157 / 32);
        System.out.println("Floor: "+floorValue);
        System.out.println("Ceil: "+ceilValue);

    }

}

-3
int total = (157-1)/32 + 1

या अधिक सामान्य

(a-1)/b +1 

मुझे लगता है कि यह काम करता है, लेकिन आपने वास्तव में समझाया नहीं है कि मूल संस्करण क्यों काम नहीं करता है।
टेपेइमम

" हालांकि कृपया ध्यान दें कि यह = 0 और b <1 के लिए काम नहीं करता है "
IG Pascual
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.