
修改并解析批處理平閏年判斷公式大家在平常的批處理計算中用到如下公式來判斷平閏年:set /a yp=!(year%%4)&!(!(year%%100))|!(year%%400)在上式中當yp的值為1時即表示year為閏年,當yp的值為0是即表示year為平年。也許有人會問了,當yp為其他值呢(不為1也不為0)?其實上式中的yp只有可能是1或0,為什么,下面我就來解釋解釋:首先我們來認識一下“!”,請注意在這里它不是我們平常開啟變量延遲時所用的變量符號“!”,它在運算式中充當的角色是一元運算符,因此在開啟變量延遲的情況下請注意使用^將其轉義。那么這個一元運算符“!”究竟是起得什么作用呢?它所起的作用就是將任意結果值變為0和1,當其運算的對象值不為0時,其運算結果為0,只有當其運算的對象值為0時,其運算結果才為1。如果你不是很明白就請在cmd中set /a a=!b,然后任意更換b的值看a值的變化吧。其次,我們再來認識一下%%運算符,沒錯它就是我們經常用到的取余運算符,set /a a=b%%c,取b/c的余數,其實在cmd中寫法是set /a a=b%c與批處理還是有所區別的。關于取余運算在論壇有大量的帖子進行了描述,在這里我就不再贅述了。只是我們將這個取余和一元運算符結合起來,如set /a a=!(b%%c),當b能整除c時a值為1反之則為0,這一點我相信大家都能明白。接下來,我們再認識三個位運算符號“&”“^”“|”,它們分別是按位與、按位異、按位或、為了方便理解,請大家忽視掉“按位”這兩個關鍵字,這是在二進制的位概念。而在這里我們面對只是1和0的位運算(因為一元運算符運算后只會產生1和0的結果,以下的運算式中我們也只考慮這一特殊情況),所以不存在按位的問題。set /a a=b&c只有bc都為1時a才為1否則為0,set /a a=b^c只有bc為一0一1時a才為1否則為0,set /a a=b|c當bc中任一個為1時a為1否則為0。對了在這里我還要解釋一個概念,什么是閏年?所謂閏年是指同時能整除100和400以及不能整除100卻能整除4的年份,那么,所有的年份整除4、100、400就只有四種情況,第一種情況能整除400的就能整除100和4(閏年);第二種情況不能整除400但能整除100和4(平年);第三種情況不能整除400和100但能整除4(閏年);第四種情況不能整除400、100和4(平年)。分別舉例如:2000是閏年,1900年是平年,2048年是閏年,1721年是平年。好了,現在我們來分析最上面的公式set /a yp=!(year%%4)&!(!(year%%100))|!(year%%400),當年份year值為第一種情況時year%%4 year%%100 year%%400的值都是0,一元運算后值都是1,大家注意到!(!(year%%100))這里實際做了兩次一元運算,也就是說公式可以簡化成 set /a yp=1&0|1,運過上面學到的位運算知識,我們不難得出yp=1;當year值為第二種情況時,year%%4的值為0,一元運算后為1,year%%100的值為0,兩次一元運算后值為0,year%%400的值不為0,一元運算后值為0,公式簡化為set /a yp=1&0|0,yp=0,后面兩種情況相信大家都能同樣推算出來了。所以上面公式的值只有可能是1或0。可以說這個公式真的很經典很牛b,在相當長的一段時間內我都是嚴格按照原作者的思路來背寫公式并運用到各種批處理閏年判斷運算中去的。但是,今天再一次看到這個公式時突然想到了按位異運算符“^”的作用,并再次分析了公式的運算情況,終于改寫了這一公式如下,雖然變化不是很大,但總算精簡了原公式并更便于大家理解:set /a yp=!(year%%4)^!(year%%100)|!(year%%400)(大家仔細觀察相對于原公式的變化)為什么能這樣改寫?原因如下:實際上我們就是要在公式中實現1運算1運算1=1,1運算1運算0=0,1運算0運算0=1,0運算0運算0=0這四種情況(1代表整除后一元運算0代表不能整除后一元運算),原公式1&!1|1=1,1&!1|0=0,1&!0|0=1,0&!0|0=0,而改寫公式后1^1|1=1,1^1|0=0,1^0|0=1,0^0|0=0,完全可以滿足所有條件。

