两次巧合的203再次印证了菜农公式与蔡勒公式同心不同路的推论

2009年04月03日 00:21    发布者:hotpower
HotC51 发表于 2009-3-11 07:33 裸奔式实时操作系统HotTask51 ←返回版面
楼主: 两次巧合的203再次印证了菜农公式与蔡勒公式同心不同路的推论

蔡勒公式如下:
W = - 2C + y + + + d - 1
或者是:w=y++-2c++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后不会出现负数
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
HotC51 发表于 2009-3-11 05:49 裸奔式实时操作系统HotTask51 ←返回版面
楼主: 菜农自贺5年后数组汇编82字节雷翻了dengm同志90字节的万年历汇编
/*-----------------------------------------------------------------------
        函数Week(macro_U16_arg1, macro_U8_arg2, macro_U8_arg3)
入口:
        macro_U16_arg1 年(0x00~0x9999)BCD码
        macro_U8_arg2  月(0x01~0x12)BCD码
        macro_U8_arg3  日(0x01~0x31)BCD码
出口:
        macro_U8_Result 星期(0~6)
长度:   82字节
-----------------------------------------------------------------------*/
macro_Function_Arg3 (Week, macro_U16_arg1, macro_U8_arg2, macro_U8_arg3)
{
#define Week_LOOP -20
    asm_MOV_R1(4),//将百年、年、月、日的BCD码换成二进制数
//Week_LOOP:
    asm_MOV_A(0x4f),//DataBuffer偏移,程序长度
//分别取出macro_U16H_arg1,macro_U16L_arg1macro_U8_arg2, macro_U8_arg3
    asm_MOVC_A_aDPTR(),
    asm_MOV_R0_A(),
    asm_MOV_A_iR0(),
    asm_ANL_A(0x0f),
    asm_XCH_A_iR0(),
    asm_SWAP_A(),
    asm_ANL_A(0x0f),
    asm_MOV_B(10),
    asm_MUL_AB(),
    asm_ADD_A_iR0(),
    asm_MOV_iR0_A(),
    asm_INC_DPTR(),
    asm_DJNZ_R1(Week_LOOP),//四次未完继续
//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7,特别注意1月2月的年为"去年"
    asm_CJNE_Rn(macro_U8_arg2, 0x03, 0),//判断月
    asm_JNC(size_MOV_A_Rn() + size_ORL_A() + size_MOV_Rn_A() \
            + size_DEC_Rn() + size_CJNE_Rn() + size_DEC_Rn()),//月
//月<=2
    asm_MOV_A_Rn(macro_U8_arg2),
    asm_ORL_A(0x04),//1月2月同5月六月表
    asm_MOV_Rn_A(macro_U8_arg2),
    asm_DEC_Rn(macro_U16L_arg1),//1月2月的年为"去年"
    asm_CJNE_Rn(macro_U16L_arg1, 0xff, size_DEC_Rn()),//Week_Start
    asm_DEC_Rn(macro_U16H_arg1),
//Week_Start:
//百年%4*5
    asm_MOV_A_Rn(macro_U16H_arg1),//百年
    asm_ANL_A(0x03),
    asm_MOV_Rn_A(macro_U16H_arg1),//百年%4
    asm_CLR_C(),
    asm_RLC_A(),
    asm_CLR_C(),
    asm_RLC_A(),//百年%4*4
    asm_ORL_A_Rn(macro_U16H_arg1),//百年%4*5
    asm_MOV_Rn_A(macro_U16H_arg1),//保存(百年%4*5),最大值3*5=15
//年+年/4
    asm_MOV_A_Rn(macro_U16L_arg1),//年
    asm_CLR_C(),
    asm_RRC_A(),
    asm_CLR_C(),
    asm_RRC_A(),
    asm_ADD_A_Rn(macro_U16L_arg1),//年+年/4
    asm_MOV_Rn_A(macro_U16L_arg1),//保存(年+年/4),最大值99+25=124
    asm_MOV_A_Rn(macro_U8_arg2),//月
    asm_MOV_B(13),
    asm_MUL_AB(),//13*月->A
    asm_MOV_B(8),
    asm_ADD_A_B(),//13*月+8
    asm_MOV_B(5),
    asm_DIV_AB(),//(13*月+8)/5 商->A
    asm_MOV_Rn_A(macro_U8_arg2),//保存((13*月+8)/5)最大值33
//日
    asm_ADD_A_Rn(macro_U8_arg3),//日,最大值31
    asm_ADDC_A_Rn(macro_U16H_arg1),//(百年%4*5),最大值15
    asm_ADDC_A_Rn(macro_U16L_arg1),//(年+年/4),最大值99+25=124
/*
此时ACC最大为15+124+33+31=203,
注意,蔡勒公式内无203.-2*C可能会越界,菜农给出的蔡勒公式完整表述:
W = (203+C/4-2*C+Y+Y/4+(13*M+8)/5+D)%7
菜农星期公式:
W = (    C%4*5+Y+Y/4+(13*M+8)/5+D)%7
*/
    asm_MOV_B(7),//取余数%7
    asm_DIV_AB(),
    asm_XCH_A_B(),
    asm_MOV_Rn_A(macro_U8_Result),//送返回值(星期)
    macro_return(),
//数据区DataBuffer
    asm_DB(macro_U16H_arg1),
    asm_DB(macro_U16L_arg1),
    asm_DB(macro_U8_arg2),
    asm_DB(macro_U8_arg3)
};

注意:“此时ACC最大为15+124+33+31=203,”
再次从另外一路方法印证了蔡勒公式应该加203来防止溢出。
当然122年前人算是不会出现问题的,但直接用于编程肯定有bug

网友评论

chj_macong 2010年09月18日
太人才了
wenjin0386 2010年09月19日
真的要多学点菜农了