Board logo

标题: [数值计算] 批处理怎样判断指定年份是平年还是闰年? [打印本页]

作者: 随风    时间: 2008-4-18 23:48     标题: 批处理怎样判断指定年份是平年还是闰年?

用批处理如何 判断指定年份是平年还是闰年?
比如:
set n=2000
效果:显示2000年是 闰年。
:对于 namejm 的这句代码看不懂,谁能解释一下?

  1. set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
复制代码

[ 本帖最后由 随风 于 2008-4-19 01:14 编辑 ]
作者: melansky    时间: 2008-4-19 00:22

应该是除以四的值&除100的值|除400的值
作者: youxi01    时间: 2008-4-19 08:10     标题: 回复 1楼 的帖子

说不清楚,最好自己去测试。
简单的测试代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a sy=2008
  3. set /a leap="^!(sy %% 100)"
  4. echo %leap%
  5. pause>nul
复制代码
注意:涉及大位运算,可以参看 set /?
作者: 随风    时间: 2008-4-19 09:06

关键是这里面的两个管道符号搞不懂是什么意识?
set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
好像在set /a 里面不是起管道作用吧?
作者: youxi01    时间: 2008-4-19 09:13

异或运算
作者: 随风    时间: 2008-4-19 09:32

  1. set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
复制代码
总算看懂了这段代码的一部分,现根据这段代码得出计算闰年的方法如下:
不管能否被4和100整除,只要能被400整除的就是闰年。
若不能被400整除,但能被4整除,且不能被100整除的也是闰年。
=================================================================
但仍然不懂代码中的 & 和 | 符号是干什么的?
上面代码中的三个取余部分,
1、能被4整除,结果为:1
2、能被100整除,结果为:0
3、能被400整除,结果为:1
将上面的代码分解如下:
:
  1. @echo off
  2. set /a leap="(0&0|1)"
  3. echo %leap%
  4. set /a leap="(0&1|1)"
  5. echo %leap%
  6. set /a leap="(1&0|1)"
  7. echo %leap%
  8. set /a leap="(1&1|1)"
  9. echo %leap%
  10. echo\&echo 不管能否被4和100整除,只要能被400整除的就是闰年。
  11. echo.
  12. set /a leap="(1&1|0)"
  13. echo %leap%
  14. echo\&echo 若不能被400整除,但能被4整除,且不能被100整除的也是闰年。
  15. echo.
  16. set /a leap="(0&0|0)"
  17. echo %leap%
  18. set /a leap="(0&1|0)"
  19. echo %leap%
  20. set /a leap="(1&0|0)"
  21. echo %leap%
  22. echo\&echo 剩下的就是平年。
  23. echo\&pause
复制代码

作者: foxJL    时间: 2008-4-20 02:01

我理解的,不知道正不正确

& 按位与
0 & 0=0
1 & 0=0
0 & 1=0
1 & 1=1

| 按位或
0 | 0=0
1 | 0=1
0 | 1=1
1 | 1=1

^ 按位异或
0 ^ 0=0
1 ^ 1=0
0 ^ 1=1
1 ^ 0=1

公历闰年的简单计算方法
能被4整除而不能被100整除,
能被100整除也能被400整除.

如:
  1. @echo off
  2. cls
  3. setlocal enabledelayedexpansion
  4. set sy=800
  5. ::设年份为800
  6. set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
  7. ::!(sy %% 4)
  8. ::800能被4整除所以为0
  9. ::1 ^ 0=1
  10. ::^!(^!(sy %% 100))
  11. ::800能被100整除也得0,
  12. ::1 ^ 0=1
  13. ::1 ^ 1=0
  14. ::^!(sy %% 400)
  15. ::800也能被400整除得0
  16. ::1 ^ 0=1
  17. ::最后
  18. ::leap=set /a leap="(1&0|1)" 结果为1
  19. echo %leap%
  20. pause
复制代码

作者: 随风    时间: 2008-4-20 02:41     标题: 回复 7楼 的帖子

就这个代码来说,好像没有用到 ^ 计算,^ 在这里应该是因为开启了延迟变量,起转义作用
用到的运算符应该是  & | ! 这三种吧。
作者: namejm    时间: 2008-4-27 09:45

  是的,因为开启了变量延迟功能,所以需要对作为运算符号的!转义,否则,将会被解释器视为变量引用;用到的运算符只有 & | ! 这三个。实际上,这条语句是我照搬 willsort 的,! 运算的具体含义我也不是很懂^_^。
作者: 随风    时间: 2008-4-27 10:12

set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
namejm 都不懂? 不会吧。。
对这段代码,我目前只有 & 符号似懂非懂,其它的都好理解。
& 有人通俗的给我解释为 × 即:乘法,若是这样,那这个代码就明白了。
对于这些  异、域、位什么的。学c的人应该懂吧。谁能讲讲就好。
作者: namejm    时间: 2008-4-27 10:28

  呵呵,我是说 ! 运算的具体含义不是很懂,整条语句的意思还是比较清楚的^_^。
作者: foxJL    时间: 2008-4-27 10:49

我认为用到的是 &  |  ^ 这三个运算符.因为在开启变量延迟功能的时候!符号都是无效的,就算用^引用.
作者: 随风    时间: 2008-4-27 10:54

h呵呵,看来 foxjl 还没能真正理解这个代码,
你把他分开来测试就知道了
set /a leap="^!(3 %% 4) "
结果是0 说明什么?
作者: xiaoxx    时间: 2008-4-27 10:54

/a决定了是算术表达式
&符号 表示的是"并且"
以0代表假 1代表真来说  
A&B的意思是:只有A为真"并且"B为真,整个表达式的值才为真(1),否则为假(0)

!就是取反 !1等于0  !0等于1

闰年定义是 能被4整除"并且"不能被100整除 "或者" 能被400整除

|的意思是"或者"
A|B 的意思是:只要A"或者"B有一个为真,整个表达式的值就为真.
作者: 随风    时间: 2008-4-27 11:06

  1. 多谢楼上
  2. 还有个问题请教
  3. set /a w="12&5"
  4. 结果为 4
  5. 12 的2 进制为 1100
  6. 5 的 2 进制为 101 补0后为 0101
  7.   1100
  8. & 0101
  9. -------
  10. 结果:4
  11. 能说下结果是怎么得到的 4 吗?
复制代码

作者: 随风    时间: 2008-4-27 11:08

明白了,结果是2进制 100 转成 10 进制后就是 4
作者: xiaoxx    时间: 2008-4-27 11:14

1100
  0101
=0100 就是4啊
作者: foxJL    时间: 2008-4-27 11:24

多谢各位,原来!是取反,这样就好理解了.
现在才知道在开启变量延时的情况下引有!也可以做运算符.^_^




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2