讨论及论证过程详见:https://bbs.21ic.com/club/bbs/list.asp?boardid=11&page=1&t=3063061
今日方敢自称菜农星期算法为“菜农星期公式”~~~
因为“菜农公式”竟然与“蔡勒公式”结果完全相同! 哈哈~~~不同菜农就栽了~~~ 结果当然必须相同,但过程和推导方法虽然雷同,可公式的优化和“物理意义”及“路径”差距很大。 菜农不知蔡勒(Zeller)是何须人也,也不知是“什么朝代”人士, 也不想知道~~~估计也是“卖脑浆的主”~~~ 首先对比2个算法: 蔡勒公式如下: W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1 或者是:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
菜农补充“完整的蔡勒公式”: W = (203 + C/4 - 2C + y + y/4 + 13 * (M+1) / 5 + d - 1) % 7 或者是:w=(203+y+y/4+c/4-2c+26(m+1)/10+d-1)%7 其中:C<=99,w在加203后不会出现负数
菜农公式如下: W = (C%4*5+Y+Y/4+(13*M+8)/5+D)%7 菜农的(13*M+8)/5是根据月星期表推导出的。 菜农依据表的万年某日星期算法: 公式:某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7 通用星期偏差表 闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 29 31 30 31 30 31 31 30 31 30 31 星期 3 6 0 3 5 1 3 6 2 4 0 2 平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 28 31 30 31 30 31 31 30 31 30 31 星期 4 0 0 3 5 1 3 6 2 4 0 2 或(1月2月为5月6月星期表): 公式:某日星期几=(百年%4*5天+年+年/4+月星期表+日-0天)%7 通用星期偏差表(此表是菜农公式中的(13*M+8)/5) 闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 29 31 30 31 30 31 31 30 31 30 31 星期 5 1 2 5 0 3 5 1 4 6 2 4 平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 28 31 30 31 30 31 31 30 31 30 31 星期 6 2 2 5 0 3 5 1 4 6 2 4
故蔡勒用的星期表为(1月2月为13月14月星期表): 公式:某日星期几=(百年/4-2*百年+年+年/4+月星期表+日-1天)%7 蔡勒星期偏差表(此表是蔡勒公式中的13*(M+1)/5) 闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 13月 14月 天数 31 29 31 30 31 30 31 31 30 31 30 31 31 29 星期 5 1 2 5 0 3 5 1 4 6 2 0 3 5 平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 13月 14月 天数 31 28 31 30 31 30 31 31 30 31 30 31 31 28 星期 6 2 2 5 0 3 5 1 4 6 2 0 3 5
根据21ic网友xwj的推导:
xwj 发表于 2008-9-6 19:56 侃单片机 ←返回版面 | 18楼: 典型的1阶比例计算,公式可以这样简化: |
蔡勒公式如下: W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1 或者是:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 -->> w=(5/4)y -(7/4)c +(26/10)m +26/10 +d -1 -->> w=(5/4)y -(7/4)c +d +(26/10)m +16/10 -->> w=(5/4)y -(7/4)c +d +(26m+16)/10
-->> w=(5/4)y -(7/4)c +d +(26m+16)/10 +N个7
|
|
xwj 发表于 2008-9-6 20:12 侃单片机 ←返回版面 | 19楼: 考虑取值范围,为了避免溢出,机器最后可以这样计算: |
w=y +y/4 -c*7/4 +d +(13*m+8)/5 +N个7
|
|
当C<=99时,2*C<=198,为使蔡勒公式不出现负数,取N=29即N*7=203 故有蔡勒公式的完整表述: W = (203+C/4-2*C+Y+Y/4+(13*M+8)/5+D)%7
注意反推(13*M+8)/5+D到13*(M+1)/5+D-1 (13*M+8)/5+D=(13*M+8+5-5)/5+D =(13*M+13)/5-5/5+D = 13*(M+1)/5+D-1
对比菜农公式: W = (C%4*5+Y+Y/4+(13*M+8)/5+D)%7 难道(203+C/4-2*C)%7和(C%4*5)%7相等吗??? 编过计算机程序的人一眼可以看出C%4*5的表述实际为: (C&3)*5 或((C&3)<<2)|(C&3). 即把C的值取低2位(D1D0)复制到高2位(D3D2) 因为C&3=0~3或00B~11B 所以C%4*5只有4个取值0(0000B),5(0101B),10(1010B),15(1111B) 则((C%4)*5)%7对应0,5,3,1 可以看出C%4*5的表述和“物理意义”非常清晰:
hotpower 发表于 2008-9-6 09:34 侃单片机 ←返回版面 | 12楼: 这个算法实际是把月星期表进行了代换 |
月星期表+日+2天 等效为公式 (13 * m + 8)/ 5
再“转帖”我当时的“四百年历”的帖子: 推导过程: 1。平年365天(52周+1天),闰年366天(52周+2天)。平年2月28天,闰年2月29天。 由于公元1月1日设为星期六,故3月1日为星期三。 ——注意这个“三” 为使算法达到最简,故本算法以“星期”为计算单位。且选3月1日为基月。 2。每400年整一闰,或每4年且不为百年的一闰。 百年%4=0闰或(年%4=0并且年<>0)闰。 3。每 4年(3个平年+1个闰年)共208周+5天 ——注意这个“5天” 每百年共100*(208周+5天)-1天=5217周+5天 ——注意这个“5天”(整 百年暂设为平年) 每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和 “1天”(4个整百年只有一个闰年) 即400年一轮回!(原来万年历400年前是一家) 4。万年3月1日星期算法(记住那个三) 公式:某年3月1日星期几=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7 某年3月1日星期几=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7 或 某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7 闰4百年3月1日星期算法(百年%4=0) 公式:某年3月1日星期几=(年+年/4+月星期表+日+2天)%7 例:0000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三 1600年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三 2000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三 2001年3月1日星期几=(1+1/4+0+1+2)%7=4%7=星期四 2004年3月1日星期几=(4+4/4+0+1+2)%7=8%7=星期一 2008年3月1日星期几=(8+8/4+0+1+2)%7=13%7=星期六 2042年3月1日星期几=(42+42/4+0+1+2)%7=55%7=星期六
平4百年3月1日星期算法(百年%4<>0) 公式:某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7 例:1700年3月1日星期几=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:1700年是平 年) 1800年3月1日星期几=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:1800年是平 年) 1900年3月1日星期几=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:1900年是平 年) 1901年3月1日星期几=(19%4*5+1+1/3+0+1+2)%7=19%7=星期五 1918年3月1日星期几=(19%4*5+18+18/4+0+1+2)%7=(15+22+3)%7=40%7=星期五 1958年3月1日星期几=(19%4*5+58/4*5+58%4+3)%7=(15+70+2+3)%7=90%7=星期六 1988年3月1日星期几=(19%4*5+88/4*5+88%4+3)%7=(15+110+0+3)%7=128%7=星期二 1999年3月1日星期几=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一 2100年3月1日星期几=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意: 2100年是平年) 2101年3月1日星期几=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二 2102年3月1日星期几=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三 2103年3月1日星期几=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四 2104年3月1日星期几=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意: 2104年是闰年) 9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一 注:按400年一轮回!(400年前是一家)的说法 1600年,2000年是一样的 1700年,2100年是一样的 1800年,2200年是一样的 1900年,2300年是一样的 所以,万年历实际上是骗人的,应该叫“四百年历”才是。万只是多的意思罢了。 5. 万年某日星期算法 公式:某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7 通同星期偏差表 闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 29 31 30 31 30 31 31 30 31 30 31 星期 3 6 0 3 5 1 3 6 2 4 0 2 平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 天数 31 28 31 30 31 30 31 31 30 31 30 31 星期 4 0 0 3 5 1 3 6 2 4 0 2
可以看出: 月星期表实际是根据(闰年/平年,天数)得到星期数的。 它实际是个固定的数,只要分清闰年/平年即可。
新算法:星期=(百年%4*5+年+年/4+(13*月+8)/5+日)%7 旧算法:星期=(百年%4*5天+年+年/4+月星期表+日+2天)%7
|
|
昨日首次“拜读”了蔡勒公式,对-2C一直迷茫~~~ 既然((C%4)*5)%7对应0,5,3,1 那么(203+C/4-2*C)也对应0,5,3,1??? C=0, (203+0/4-2*0)%7=203%7=0 C=1, (203+1/4-2*1)%7=(203-2)%7=5 C=2, (203+2/4-2*2)%7=(203-4)%7=3 C=3, (203+3/4-2*3)%7=(203-6)%7=1 C=4, (203+4/4-2*4)%7=(203+1-8)%7==(203+0)%7=0 C=5, (203+5/4-2*5)%7=(203+1-10)%7=(203-2)%7=(203+5)%7=5 C=6, (203+6/4-2*6)%7=(203+1-12)%7=(203-4)%7=(203+3)%7=3 C=7, (203+7/4-2*7)%7=(203+1-14)%7=(203+1-0)%7=(203+1)%7=1 C=8, (203+8/4-2*8)%7=(203+2-16)%7=(203-14)%7=(203+0)%7=0 晕呀!!! 蔡勒公式中的-2C竟然是想得到重复的0,5,3,1序列采取的“手段”
最后还有个1月2月变换问题,蔡勒公式取13月14月,菜农取5月6月。
因为菜农公式是在月星期表“进化”而来,又因为13月14月与5月6月的表值相同, 所以最后决定改为1月2月变换为5月6月。
这样做现在看来“物理意义”失去,但当时考虑“月表”的M大于12就不成“月”了.
总之把握:
1月2月为去年的以3月为基月表的表尾。
所以:
公式中出现1月2月的年是“去年”!!!
公式中出现1月2月的月是“明年”!!!(13月14月下一年的1月2月)
这样“去年”和“明年”就“能量守恒”了~~~
到此菜农“反汇编”蔡勒公式终成正果~~~ 感觉蔡勒公式确实和菜农公式在思路上有很大的差距~~~ 哈哈~~~看来蔡勒“同志”的脑浆还是“白颜色”的~~~
最后给出完整的菜农公式:
W = (C%4*5+Y+Y/4+(13*M+8)/5+D)%7
其中:
C=1~XX,Y=0~99,M=1~12,D=1~28/29/30/31
计算时要注意1月和2月的“去年”“明年”变换。
即:
当M=1或2时,M=M+12或M=M+4,Y=Y-1;当结果Y<0时,C=C-1.
哈哈~~刚搜索的:
蔡勒公式最早是由德国数学家克里斯蒂安 · 蔡勒( Christian Zeller, 1822-1899 )在 1886 年推导出的,因此通称为蔡勒公式( Zeller’s Formula )。为方便口算,式中的 [13 * (M+1) / 5] 也往往写成 [26 * (M+1) / 10] 。
哈哈~~~122年前就有蔡勒公式,菜农深感惭愧~~~
向蔡勒同志敬礼!!!
菜农HotPower@126.com 2008.9.6 23:18 于西安大雁塔菜地 相关链接:http://blog.**/hotpower/158297/message.aspx |