2012-03-24 10 views
16

किसी आईएसओ कैलेंडर के लीप वर्ष (: Odd bit manipulations लिंक): जाँच के लिए एक आश्चर्यजनक तेजी से कार्यान्वयन गिरालीप वर्ष बिटवाइज़ ऑपरेटर्स (आश्चर्यजनक गति) का उपयोग कर जांच JSPerf पर

function isLeapYear(year) { 
    return !(year & 3 || year & 15 && !(year % 25)); 
} 

Node.js का उपयोग करना, मैं जल्दी से जाँच की यह मुझे पता है कि दो अन्य एक लाइनर कार्यान्वयन के खिलाफ।

function isLeapClassic(y) { return (y % 4 == 0) && !(y % 100 == 0) || (y % 400 == 0); } 
function isLeapXOR(y) { return (y % 4 == 0)^(y % 100 == 0)^(y % 400 == 0); } 
function isLeapBitwise(y) { return !(y & 3 || y & 15 && !(y % 25)); } 

//quick'n'dirty test on a small range! 
//works with negative integers too 
for (var i = 1900; i <= 2100; i++) { 
    console.log(
     "year = %d,\t%d%d%d", 
     i, 
     isLeapClassic(i), 
     isLeapXOR(i), 
     isLeapBitwise(i) 
    ); 
} 

यह अपेक्षा के अनुसार काम करता है, लेकिन मेरी समस्या यह है कि मैं कैसे नहीं समझ सकता। मुझे ((a % b) == (a & (b-1)) पता है जब बी दो (year % 4) == (year & 3) की शक्ति है, लेकिन year & 15 && !(year % 25) पता लगाने में काफी मुश्किल है। क्या कोई मुझे समझा सकता है कि यह कैसे काम करता है? इस कार्यान्वयन के बारे में कोई संदर्भ?

+2

जिज्ञासा से बाहर: अनुकूलित करने के लिए उपयोगकेस वास्तव में क्या है? – user123444555621

+0

अद्भुत गति! यह दिलचस्प है अगर आप पाठ्यक्रम की लाइब्रेरी लिखने की योजना बना रहे हैं! – Redger

+0

मैं नैनोसेकंद के प्रदर्शन लाभ के लिए कभी भी पठनीयता को त्याग नहीं दूंगा। – user123444555621

उत्तर

13

year & 3year % 4 जैसा ही है। वहां इतना मुश्किल नहीं है, यह सिर्फ सामान्य 4-वर्ष चक्र का प्रतिनिधित्व करता है।

year & 15year % 16 जैसा ही है।

इसलिए, यह नहीं एक लीप वर्ष है कि अगर साल 4 से समान रूप से विभाजित नहीं है, या अगर यह 16 से समान रूप से विभाजित नहीं होता लेकिन 25 से समान रूप से विभाजित करता है इसका मतलब है कि 25 के हर एक से अधिक नहीं है एक लीप वर्ष जब तक कि यह 16 का बहुमत न हो। 16 से 25 के पास कोई सामान्य कारक नहीं है, केवल एक ही समय दोनों शर्तों को पूरा किया जाता है जब वर्ष 16 * 25, या 400 साल का एक बहु होता है। 100 * चक्र के लिए लेखांकन, 4 * 25 के गुणक लीप साल नहीं माना जाएगा।

1 9 00 एक लीप वर्ष नहीं था क्योंकि यह 100, 2000 द्वारा विभाजित किया गया था एक लीप वर्ष था क्योंकि यह 400 से विभाजित था, और 2100 एक लीप वर्ष नहीं होगा।

+2

सर्वोत्तम विस्तृत उत्तर! – Redger

+0

यह भी देखें http://stackoverflow.com/a/11595914/733805 –

+0

आपकी विस्तृत व्याख्या मेरे लिए इस दिन-दर-महीने कोड में इस एल्गोरिदम का उपयोग करती है http://stackoverflow.com/questions/1810984/number-of- दिन-में-किसी भी महीने/27946635 # 27946635 (मूल रूप से मैं समाधान में कोड का उपयोग नहीं करता जब तक कि मैं इसे पूरी तरह समझ नहीं पाता)। महान विवरण के लिए धन्यवाद और +1 :) –

5

यदि कोई संख्या 16 तक विभाजित है और 25 तक विभाजित है, तो यह चार गुना 25 (100) के साथ-साथ 16 गुना 25 (400) से विभाजित है।

+0

तो 400 से 400 से विभाजित कैसे किया जाता है? – Gareth

+0

उत्तर अपडेट किया गया क्योंकि मुझे यह सुनिश्चित करना था कि मैं सही था :-) – Pointy

संबंधित मुद्दे