दिलचस्प पोस्ट
मूल्य पैरामीटर के लिए निरंतरता अनिर्धारित स्थानीय चर सबसे तेजी से यादृच्छिक संख्या जनरेटर है? एंड्रॉइड डिज़ाइन विचार: AsyncTask बनाम सेवा (IntentService?) लूप अनुदेश धीमा क्यों है? इंटेल ने इसे कुशलतापूर्वक लागू नहीं किया? ओपनलाइन बनावट को निर्देशांक कैसे काम करता है? लंबे समय से मतदान, वेबसकेट्स, सर्वर से भेजे गए इवेंट्स (एसएसई) और धूमकेतु क्या हैं? सी # ग्लोबल वैरिएबल्स सी # सूचीदृश्य कॉलम चौड़ाई ऑटो पायथन: defaultdict का डिफ़ॉल्ट दिशानिर्देश? ऐड-ऑन से Google डॉक का चुनाव कैसे करें एंड्रॉइड – टुकड़ा स्थिति सहेजें / पुनर्स्थापित करें HTTP फ़ाइल कैसे अपलोड करती है? क्या रूबी की स्ट्रिंग प्रक्षेप के लिए एक पायथन बराबर है? कैसे जावा इंटरफेस कई विरासत अनुकरण करते हैं? कैसे एक जावा कार्यक्रम Daemonize करने के लिए?

सी में लीप वर्ष को प्रोग्राम में कैसे खोजें

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

#include<stdio.h> #include<conio.h> int yearr(int year); void main(void) { int year; printf("Enter a year:"); scanf("%d",&year); if(!yearr(year)) { printf("It is a leap year."); } else { printf("It is not a leap year"); } getch(); } int yearr(int year) { if((year%4==0)&&(year/4!=0)) return 1; else return 0; } 

टिप्पणियाँ पढ़ने के बाद मैंने अपनी कोडिंग को संपादित किया:

 #include<stdio.h> #include<conio.h> int yearr(int year); void main(void) { int year; printf("Enter a year:"); scanf("%d",&year); if(!yearr(year)) { printf("It is a leap year."); } else { printf("It is not a leap year"); } getch(); } int yearr(int year) { if((year%4==0) { if(year%400==0) return 1; if(year%100==0) return 0; } else return 0; } 

वेब के समाधान से एकत्रित समाधान "सी में लीप वर्ष को प्रोग्राम में कैसे खोजें"

लीप वर्ष निर्धारित करने के लिए आपका तर्क गलत है आपको इसे शुरू करना चाहिए (विकिपीडिया से):

 if year modulo 400 is 0 then is_leap_year else if year modulo 100 is 0 then not_leap_year else if year modulo 4 is 0 then is_leap_year else not_leap_year 

x modulo y मतलब है x का शेष y विभाजित होगा। उदाहरण के लिए, 12 मॉड्यूल 5 5 है

सबसे कुशल लीप वर्ष परीक्षण:

 if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) { /* leap year */ } 

यह कोड सी, सी ++, सी #, जावा, और कई अन्य सी-जैसे भाषाओं में मान्य है। कोड एक एकल TRUE / FALSE अभिव्यक्ति का उपयोग करता है जिसमें तीन अलग-अलग परीक्षण होते हैं:

  • चौथा वर्ष का परीक्षण: year & 3
  • 100 वीं वर्षीय परीक्षा: year % 25
  • 400 वीं वर्षीय परीक्षा: year & 15

यह कोड कैसे काम करता है, इस बारे में पूरी चर्चा नीचे दिखाई देती है, लेकिन पहले विकिपीडिया के एल्गोरिथ्म की चर्चा के लिए कहा जाता है:

विकिपीडिया एल्गोरिदम अनन्य / अनन्य है

विकिपीडिया ने छद्म कोड एल्गोरिदम प्रकाशित किया है (देखें: लीप वर्ष – एल्गोरिदम ) जिसे लगातार संपादन, राय और बर्बरता के अधीन किया गया है।

WIKIPEDIA ALGORITHM लागू नहीं करें!

सबसे लंबे समय तक खड़े (और अक्षम) विकिपीडिया एल्गोरिदम में से एक निम्नानुसार दिखाई दिया:

 if year modulo 400 is 0 then is_leap_year else if year modulo 100 is 0 then not_leap_year else if year modulo 4 is 0 then is_leap_year else not_leap_year 

उपरोक्त एल्गोरिथ्म अक्षम है क्योंकि यह हमेशा 400 वें वर्ष और 100 वें वर्ष के लिए भी ऐसे परीक्षण करता है जो "चौथे वर्ष परीक्षण" (मॉड्यूलो 4 परीक्षण) में विफल हो जाएंगे-जो कि समय का 75% है! 4 वें साल के परीक्षण को पूरा करने के लिए एल्गोरिदम को फिर से क्रमबद्ध करके हम चीजों की गति को काफी महत्व देते हैं।

"अति-कुशल" PSEUDO-CODE ALGORITHM

मैंने निम्नलिखित एल्गोरिथम विकिपीडिया को प्रदान किया है (एक से अधिक बार):

 if year is not divisible by 4 then not leap year else if year is not divisible by 100 then leap year else if year is divisible by 400 then leap year else not leap year 

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

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

"अधिकतम-सक्षम" लीप वर्ष परीक्षण का विवरण

बिट-ऐंड और मॉड्यूल के स्थान पर:

मैंने विकिपीडिया एल्गोरिथम में दो मॉड्यूलो ऑपरेशनों को बिटवर्ड-एंड ऑपरेशन के साथ बदल दिया है। क्यों और कैसे?

एक मॉड्यूलो गणना करने की आवश्यकता होती है विभाजन। एक पीसी प्रोग्रामिंग करते समय एक बार इसके बारे में दो बार ऐसा नहीं लगता है, लेकिन छोटे उपकरणों में एम्बेडेड 8-बिट माइक्रोकंट्रोलर प्रोग्रामिंग करते समय आपको लगता है कि एक डिवाइड फ़ंक्शन CPU द्वारा निष्पादित नहीं किया जा सकता है। इस तरह की सीपीयू पर, विभाजन एक दोहरावदार पाशन, बिट स्थानांतरण, और बहुत कम धीमी गति से जोड़ना / घटाए कार्यों को शामिल करने वाली एक कठिन प्रक्रिया है। यह बचने के लिए बहुत ही वांछनीय है

यह पता चला है कि दो की शक्तियों के मॉड्यूल को बारीकी से एक बिटwise- और ऑपरेशन (देखें: विकिपीडिया संचालन – प्रदर्शन संबंधी मुद्दे ) का उपयोग करके प्राप्त किया जा सकता है:

x% 2 ^ n == x और (2 ^ एन -1)

कई अनुकूलक कंपलर ऐसे मॉड्यूलो संचालन को बिटवाइन-और आपके लिए कन्वर्ट करेंगे, लेकिन छोटे और कम लोकप्रिय सीपीयू के लिए कम उन्नत कम्पाइलर नहीं हो सकते हैं। बिट-एंड-एंड प्रत्येक सीपीयू पर एक एकल निर्देश है

modulo 4 और modulo 400 परीक्षणों को & 3 और & 15 साथ बदलकर (नीचे देखें: 'गणित को कम करने के लिए फैक्टरिंग') हम यह सुनिश्चित कर सकते हैं कि बहुत धीमी विभाजित ऑपरेशन का उपयोग किए बिना सबसे तेज़ कोड परिणाम।

इसमें दो की कोई शक्ति नहीं होती है जो 100 के बराबर होती है। इस प्रकार, हमें 100 वें साल के परीक्षण के लिए मॉड्यूलो ऑपरेशन का उपयोग जारी रखने के लिए मजबूर किया जाता है, हालांकि 100 को 25 से बदलकर (नीचे देखें)।

गणित को सरल बनाने के लिए फैक्टरिंग:

Modulo ऑपरेशन को बदलने के लिए bitwise-AND का उपयोग करने के अलावा, आप विकिपीडिया एल्गोरिदम और अनुकूलित अभिव्यक्ति के बीच दो अतिरिक्त विवादों को नोट कर सकते हैं:

  • modulo 100 को modulo 25 द्वारा बदल दिया गया है
  • modulo 400 को प्रतिस्थापित किया जाता है & 15

100 वें वर्ष का परीक्षण modulo 100 बजाय modulo 25 का उपयोग करता है। हम ऐसा कर सकते हैं क्योंकि 100 कारक 2 x 2 x 5 x 5 से बाहर होते हैं। क्योंकि चौथी साल का परीक्षण पहले से ही 4 के कारकों की जांच करता है, हम उस फैक्टर को 100 से दूर कर सकते हैं, 25 छोड़कर। यह ऑप्टिमाइज़ेशन लगभग हर सीपीयू कार्यान्वयन के लिए शायद नगण्य है ( जैसा कि दोनों 100 और 25 फिट 8-बिट्स में)

400 वें वर्ष का परीक्षण उपयोग करता है & 15 जो कि modulo 16 बराबर है। फिर से, हम ऐसा कर सकते हैं क्योंकि 400 कारक 2 x 2 x 2 x 2 x 5 x 5 के लिए। हम 25 के कारक को समाप्त कर सकते हैं, जिसे 100 वीं साल के परीक्षण से परीक्षण किया जा सकता है। हम 16 को कम नहीं कर सकते क्योंकि 8 200 का एक कारक है, इसलिए किसी भी अधिक कारकों को हटाने से 200 वें वर्ष के लिए एक अवांछित सकारात्मक उत्पादन होगा।

400-वर्षीय अनुकूलन 8-बिट CPU के लिए बहुत महत्वपूर्ण है, पहले, क्योंकि यह विभाजन से बचा जाता है; लेकिन, अधिक महत्वपूर्ण है, क्योंकि मूल्य 400 9-बिट संख्या है जो 8-बिट CPU में से निपटने के लिए बहुत मुश्किल है

लघु सर्किट तार्किक और / या ऑपरेटर:

अंतिम, और सबसे महत्वपूर्ण, उपयोग किए गए अनुकूलन शॉर्ट-सर्किट लॉजिकल एंड ('एंड एंड') और ('' ') ऑपरेटरों (देखें : शॉर्ट-सर्किट मूल्यांकन ) हैं, जो कि ज्यादातर सी-जैसे भाषाओं में कार्यान्वित हैं । शॉर्ट सर्किट ऑपरेटरों का नाम इसलिए रखा जाता है क्योंकि वे सही पक्ष पर अभिव्यक्ति का मूल्यांकन करने के लिए परेशान नहीं करते अगर बाएं ओर की अभिव्यक्ति स्वतः ही ऑपरेशन के नतीजे को तय करती है।

उदाहरण के लिए: यदि वर्ष 2003 है, तो year & 3 == 0 गलत है। ऐसा कोई रास्ता नहीं है कि तार्किक और सही के सही पक्ष पर परीक्षण परिणाम सही बना सकते हैं, इसलिए कुछ और नहीं मूल्यांकन किया जाता है

पहले चौथे वर्ष का परीक्षण करके, केवल चौथे वर्ष का परीक्षण (एक साधारण बिटवर्ड- और) का मूल्यांकन उस समय के तीन-चौथाई (75 प्रतिशत) का होता है यह प्रोग्राम निष्पादन को बहुत बढ़ाता है, खासकर जब से यह 100 वें वर्ष परीक्षण (मॉड्यूल 25 ऑपरेशन) के लिए आवश्यक डिवीजन से बचा जाता है।

प्रतिस्थापन प्लेसमेंट पर ध्यान दें

एक टिप्पणीकार को लगा कि कोष्ठक मेरे कोड में गलत थे और सुझाव दिया कि उप-अभिव्यक्ति को तार्किक और ऑपरेटर (तार्किक OR के आस-पास के बजाय) के चारों ओर पुनर्गठन किया जाना चाहिए, निम्नानुसार:

 if (((year & 3) == 0 && (year % 25) != 0) || (year & 15) == 0) { /* LY */ } 

ऊपर गलत है। तार्किक और ऑपरेटर की तार्किक या उससे अधिक श्रेष्ठता है और इसका मूल्यांकन पहले के बिना या नए कोष्ठकों के बिना किया जाएगा। तार्किक और तर्क के चारों ओर पैरेन्थेसिस का कोई प्रभाव नहीं है। यह उप-समूह को पूरी तरह से समाप्त करने के लिए एक हो सकता है:

 if ((year & 3) == 0 && (year % 25) != 0 || (year & 15) == 0) { /* LY */ } 

लेकिन, ऊपर के दोनों मामलों में, तार्किक या (400 वें वर्षीय परीक्षण) का सही पक्ष लगभग हर बार मूल्यांकन किया जाता है (यानी, साल 4 और 100 तक विभाजित नहीं)। इस प्रकार, एक उपयोगी अनुकूलन गलती से समाप्त कर दिया गया है।

मेरे मूल कोड में कोष्ठक सबसे अनुकूलित समाधान को लागू करते हैं:

 if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) { /* LY */ } 

यहां, तार्किक या केवल 4 से विभाजित होने वाले वर्षों के लिए मूल्यांकन किया जाता है (शॉर्ट सर्किट और) के कारण। तार्किक OR का सही पक्ष केवल 4 और 100 तक विभाज्य वर्षों के लिए मूल्यांकन किया गया है (शॉर्ट-सर्किट या) के कारण।

सी / सी ++ प्रोग्रामर के लिए नोट

सी / सी ++ प्रोग्रामर को लगता है कि यह अभिव्यक्ति अधिक अनुकूलित है:

 if (!(year & 3) && ((year % 25) || !(year & 15))) { /* LY */ } 

यह अधिक अनुकूलित नहीं है! जबकि स्पष्ट == 0 और != 0 परीक्षण निकाल दिए जाते हैं, वे अंतर्निहित हो जाते हैं और अभी भी प्रदर्शन किए जाते हैं। इससे भी बदतर, कोड अब दृढ़ता से टाइप की गई भाषाओं में वैध नहीं है जैसे C # जहां year & 3 एक int मूल्यांकन करता है, लेकिन तार्किक AND ( && ), OR ( || ) और NOT ( ! ) ऑपरेटरों को bool arguments की आवश्यकता होती है।

 int isLeapYear(int year) { return (year % 400 == 0) || ( ( year % 100 != 0) && (year % 4 == 0 )); } 

यद्यपि 400 द्वारा विभाजित तर्क तर्कहीन है, यह कम्प्यूटेशनल रूप से कुशल नहीं है जैसा कि पहले 4 को विभाजित करता है। आप तर्क के साथ ऐसा कर सकते हैं:

 #define LEAPYEAR(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0)) 

यह प्रत्येक मूल्य के लिए 4 से विभाजित होता है, लेकिन उनमें से 3/4 के लिए, परीक्षण समाप्त हो जाता है। 1/4 के लिए जो पहले टेस्ट पास करते हैं, तो यह 100 से विभाजित करता है, 24/25 मूल्यों को नष्ट कर देता है; शेष 100 में से 1 के लिए, यह 400 से भी विभाजित है, जो अंतिम उत्तर के साथ आ रहा है। दी, यह एक बड़ी बचत नहीं है

यह सही समाधान हो सकता है विकिपीडिया पर दी गई एल्गोरिथ्म सही नहीं है।

 -(BOOL)isLeapYear: (int)year{ if(year%4==0){ if(year%100!=0){ return YES; } else if(year%400!=0){ return YES; } else return NO; } else return NO; } 

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

लीप वर्ष पर विकिपीडिया लेख से:

 if (year modulo 4 is 0) and (year modulo 100 is not 0) or (year modulo 400 is 0) then is_leap_year else not_leap_year 

http://www.wwu.edu/depts/skywise/leapyear.html

लीप वर्ष नियम

साल में एक लीप वर्ष होता है, जिसकी संख्या पूरी तरह से चार से विभाजित होती है – साल के अलावा, जो 100 से विभाजित दोनों हैं और 400 से विभाजित नहीं हैं। नियम प्रभाव का दूसरा भाग सदी वर्ष उदाहरण के लिए; सदी के वर्ष 1600 और 2000 लीप वर्ष हैं, लेकिन सदी वर्ष 1700, 1800 और 1 9 00 नहीं हैं। इसका मतलब है कि हर चार सौ साल में तीन बार लीप वर्ष के बीच आठ साल होते हैं।

  if(year%400 ==0 || (year%100 != 0 && year%4 == 0)) { printf("Year %d is a leap year",year); } else { printf("Year %d is not a leap year",year); } 

इसे ऊपर की तरह बदलें यह भी पढ़ें।


     #शामिल 
     शून्य मुख्य (शून्य)
     {
         इंट साल;
         printf ("यह लीप वर्ष है, यह जांचने के लिए एक वर्ष दर्ज करें \ n");
         scanf ( "% d", और वर्ष);
         यदि (वर्ष% 400 == 0) / * क्यों 400 * /
             printf ("% d एक लीप वर्ष है \ n", वर्ष);
         और यदि (वर्ष% 100 == 0) / * क्यों 100 *
             printf ("% d एक लीप वर्ष नहीं है \ n", वर्ष);
         और अगर (वर्ष% 4 == 0)
             printf ("% d एक लीप वर्ष है \ n", वर्ष);
         अन्य
             printf ("% d एक लीप वर्ष नहीं है \ n", वर्ष);

     }

 I used this code: #include <stdio.h> int main() { int yr; printf ("Enter a year \n"); scanf ("%d", &yr); if (yr%400 == 0) printf("\n LEAP YEAR."); else if (yr%4==0 && yr%100!=0) printf("\n LEAP YEAR."); else printf ("\n NOT LEAP YEAR."); } 

जैसा कि अन्य ने लीप वर्ष के लिए शर्त का भी उल्लेख किया है, वह सही नहीं है। यह होना चाहिए:

 int yearr(int year) { if(((year%4 == 0) && (year%100 !=0)) || (year%400==0)) return 1; else return 0; } 

इसे यहाँ पढ़ें सी में लीप वर्ष की जांच कैसे करें

केविन का जवाब एक 8 अधिकतम परीक्षण प्रदान करता है (XOR को स्थिरांकों के साथ) लेकिन अगर आप कुछ और पठनीय खोज रहे हैं, तो 9 ऑपरेशन टेस्ट का प्रयास करें।

 year % 4 == 0 && !((year % 100 == 0) ^ (year % 400 == 0)) 

सत्य तालिका (year % 100 == 0) ^ (year % 400 == 0)

  (year % 100 == 0) ^ (year % 400 == 0) 100 doesnt divide year . F only 100 divides year . T 100 and 400 divides year . F 

अब !(year % 100 == 0) ^ (year % 400 == 0) आपको क्या चाहिए।

महीने के लिए अधिकतम / अंतिम दिन की गणना करें: 1..12, वर्ष: 1..3999

 maxDays = month == 2 ? 28 + ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) : 30 + ((month & 1) ^ (month > 7)); 

#define is_leap(A) !((A) & 3)

बस सुनिश्चित करें कि आप नकारात्मक वर्ष दर्ज नहीं करेंगे 🙂