[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[数值计算] [已解决]批处理set命令怎样计算以零开头的数字?

答案在8楼
  1. @echo off
  2. set N=0123
  3. set /a N=%N%*1
  4. echo %N%
复制代码
结果是83
为什么会这样?

我想将一个四位数变成四个数字,代码如下。只要首数字不为0,结果都正确。但是如果输入0123(允许这样输),结果却是0 0 8 3
  1. @echo off&setlocal enabledelayedexpansion
  2. set /p Num=请连续输入四个不同的数字(比如0123):
  3. set /a N1=!Num!/1000
  4. set /a Num=!Num!-!N1!*1000
  5. set /a N2=!Num!/100
  6. set /a Num=!Num!-!N2!*100
  7. set /a N3=!Num!/10
  8. set /a N4=!Num!-!N3!*10
  9. echo !N1! !N2! !N3! !N4!
复制代码
好吧,既然set中,0开头的表示8进制,我绕着走好了。
  1. @echo off&setlocal enabledelayedexpansion
  2. set /p Num=请连续输入四个不同的数字(比如0123):
  3. set /a N1=!Num!/1000
  4. if !N1!==0 goto R8
  5. set /a Num=!Num!-!N1!*1000
  6. set /a N2=!Num!/100
  7. set /a Num=!Num!-!N2!*100
  8. set /a N3=!Num!/10
  9. set /a N4=!Num!-!N3!*10
  10. goto N4
  11. :R8
  12. echo A!Num!>ls.tmp
  13. for /f "tokens=2 delims=0" %%a in (ls.tmp) do set Num=%%a
  14. del /a /f ls.tmp
  15. set /a N2=!Num!/100
  16. set /a Num=!Num!-!N2!*100
  17. set /a N3=!Num!/10
  18. set /a N4=!Num!-!N3!*10
  19. :N4
  20. echo !N1! !N2! !N3! !N4!
复制代码
新问题发现了。如果有8 和9 还是会报错。

下面这段代码错在哪里了?假设M1到M4 N1到N4全都有值了。目的是找出相同数字的个数。
  1. @echo off&setlocal enabledelayedexpansion
  2. set b=0
  3. for  %%a in (!M1!,!M2!,!M3!,!M4!) do (
  4. for  %%a in (!N1!,!N2!,!N3!,!N4!) do (if %%a==%%b
  5. set /a b+=1  )
  6. )
复制代码
我对上述代码的理解是:将M1的值值赋给%%a,执行第二个for,分别将N1-N4的值赋给%%b,每赋一次值就和%%a比较一次。
这种理解错在哪里了?
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

0123 被看作是一个八进制数, 十进制就是 83 (1*8^2+2*8+3)

请查看如下地址的资料:
mkMSITStore:%windir%\Help\ntcmds.chm::/set.htm

Using /a
...
Numeric values are decimal numbers unless prefixed by 0× for hexadecimal numbers or 0 for octal numbers. Therefore, 0×12 is the same as 18 is the same as 022. The octal notation can be confusing. For example, 08 and 09 are not valid numbers because 8 and 9 are not valid octal digits.

数值一般是十进制数, 除非用了 0x 的前缀表示十六进制数或者用了 0 的前缀来表示八进制数.
因此 0x12 就是 18 (16*1+2), 也是 022 (2*8+2).
八进制表示法是迷惑人的. 例如, 08 和 09 是无效的数, 因为 8 和 9 是无效的八进制数码.
1

评分人数

TOP

常用手段是变量偏移或者在万位补一个非零数字

TOP

下面的形式是错误的:
  1. if a==b
  2.   statement
复制代码
详参见:
mkMSITStore:%windir%\Help\ntcmds.chm::/if.htm
  1. for %%a in (!N1!,!N2!,!N3!,!N4!) do set nb=%%a
复制代码
运行完后, nb 的值是 N4 的值, 也就是说, 对于每一个 M 变量的值, 只会与
N4 进行比较, 所以这里没有实现你期望的逻辑, 另外变量上可以简洁一些:
  1. @echo off&setlocal enabledelayedexpansion
  2. set b=0
  3. for %%a in (!M1!,!M2!,!M3!,!M4!) do (
  4.   for %%b in (!N1!,!N2!,!N3!,!N4!) do (
  5.     if %%a==%%b set /a b+=1
  6.   )
  7. )
复制代码

TOP

  1. 0123 被看作是一个八进制数, 十进制就是 83 (1*8^2+2*8+3)
复制代码
还有这种规则

TOP

5# Hello123World


set /?中有解释的。
八进制数以0开头表示,十六进制数以0x开头表示,八进制、十六进制、十进制之间可以混合计算,但均以十进制输出结果

TOP

4# neorobin


有什么办法能够实现我的想法呢?N1 N2 N3 N4分别与M1 M2 M3 M4比较,找出相同数字的个数。

TOP

本帖最后由 hanyeguxing 于 2011-4-19 11:58 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. set n=0823&set m=0935
  3. for /l %%a in (0,1,3) do set/a N_%%a=!n:~%%a,1!,M_%%a=!m:~%%a,1!
  4. for /l %%a in (0,1,3) do for /l %%b in (0,1,3) do if !N_%%a!==!M_%%b! set/a b+=1
  5. set N_&set M_&echo;%b%&pause
复制代码
楼主弄一大堆的 set /a 做什么呢?
for /l %%a in (0,1,3) do set/a N_%%a=!n:~%%a,1!,M_%%a=!m:~%%a,1! 分别将n、m截取分隔成4个数字
for /l %%a in (0,1,3) do for /l %%b in (0,1,3) do if !N_%%a!==!M_%%b! set/a b+=1 分别比较并计数
因为 for /l 迭代的少,所以 for /l %%a in (0,1,3) do 也可以写成 for %%a in (0,1,2,3) do
set/a N_%%a=!n:~%%a,1!,M_%%a=!m:~%%a,1! 也可以写成 set N_%%a=!n:~%%a,1!&set M_%%a=!m:~%%a,1!
1

评分人数

寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

返回列表