中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --
联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟
中国DOS联盟论坛
现在时间是 2026-08-25 23:21
47,812 主题排行 / 349,910 发帖 / 今日 0 篇 / 48,264 会员排行
DOS批处理 & 脚本技术(批处理室) » 关于数值运算时的进制问题!
可打印版本  3,130 / 11
第1楼 pengfei 发表于 2006-09-05 02:07
银牌会员 发帖 485 积分 1,218 来自 湖南.娄底
关于数值运算时的进制问题!
在用SET /A进行运算时, (如果字符的第一位数为零,并且数值中含有8或9), 会导致数值不能正确读取.

因为除十六进制有 0x 前缀, 八进制有 0 前缀的, 数字值为十进位数字。因此, 0x12 与 18 和 022

相同。请注意八进制公式可能很容易搞混: 08 和 09 是无效的数字,因为 8 和 9 不是有效的

八进制位数。

例:
C:\>set /a minute=08+5
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。
C:\>set /a minute=5+018
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。
C:\>set /a minute=0029+8
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。
C:\>set /a minute=125+09
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。

解决方法:

1. 在运算常量时, 如果常量中含有8或9, 前面不要加零, 总之最高位数不能为零.

例: 错误 (08, 009, 018, 0029)

正确 (8, 9, 18, 29)

2. 防止变量运算时变量的最高位数为零;

算法:
首先取变量的第一位数, 判断其是否为零;

如果成立,则取出第一位后的余数, 重新赋予变量;

执行循环直到第一位数不为零止;

最后用去零的变量进行运算.

代码:
@echo off
set mu=0001028
echo 去零前=%mu%
:again
if "%mu:~0,1%"=="0" (
set mu=%mu:~1%
goto again
)
echo 去零后=%mu%
set /a num=%mu%+154
echo 运算结果=%num%
pause

今天在写批处理脚本时遇到了这个问题, 终于把其中的原因弄明白了.

也找到了解决方法, 以后大家遇到相应的问题时可以避免走弯路.

[ Last edited by pengfei on 2006-10-2 at 09:41 ]
第2楼 vkill 发表于 2006-09-05 03:41
金牌会员 发帖 1,744 积分 4,103 来自 甘肃.临泽
恩,到没有注意这进制
第3楼 namejm 发表于 2006-09-05 05:17
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  呵呵,论坛的老贴里隐约提到过首位为0时的处理,一下子找不到那个帖子了。
第4楼 lxmxn 发表于 2006-09-29 11:14
版主 发帖 4,938 积分 11,386
学习中……
还可以用这种算法判断一个字符串中的空格数``
嘿嘿`
第5楼 redtek 发表于 2006-09-29 13:08
金牌会员 发帖 1,147 积分 2,902
顶~~
第6楼 redtek 发表于 2006-09-29 22:55
金牌会员 发帖 1,147 积分 2,902
刚才又转到这儿来了,哈哈……

:again
if "%mu:~0,1%"=="0" (
set mu=%mu:~1%
goto again
)

你写的这个 :again 和 goto again 够酷!
直到把开头的0去尽了直到IF条件自然的就不成立而跳出了跳转继续执新的内容:)
佩服~~~
第7楼 redtek 发表于 2006-09-30 00:34
金牌会员 发帖 1,147 积分 2,902
深受 pengfei 楼主的 “ :again ... goto again ” 精彩应用的启发,
学着楼主goto原理试着做了一个模拟递归求N!的实验,goto用好了真是方便~:)
再一次感谢 楼主篇“关于数值运算时的进制问题”大作~:)


计算N的阶乘:)
没有越界和没有非法检查,就是为了学习楼主的goto的运用之作~:)

第8楼 zh159 发表于 2006-09-30 00:44
金牌会员 发帖 1,467 积分 3,687

if 写成一行也OK
第9楼 lxmxn 发表于 2006-10-02 09:21
版主 发帖 4,938 积分 11,386
恩,这个算是最精简的一个方法了`
顶一个先``
第10楼 pengfei 发表于 2006-10-02 10:25
银牌会员 发帖 485 积分 1,218 来自 湖南.娄底
我当时处理这个问题的时候想到的算法是, 先提取第一位, 判断其值是否为零. 这是第一步, 那接下来代码怎么写呢? 取值和判断零都好办, 用set中的字符取位,一个IF判断就可以解决.

第二步, 如果存在多个零就需要用到循环以及重新赋值. 一想批处理中实现这样循环好像只有goto(又想到goto会不会一直循环, 但马上又看到前面一个IF不单是判断零, 还起到条件判断的作用). 到这里, 一个IF一个GOTO就构成了一个完整的算法.代码也很快写出来了...

[ Last edited by pengfei on 2006-12-7 at 11:58 AM ]
第11楼 无奈何 发表于 2006-10-02 12:16
荣誉版主 发帖 356 积分 1,338
来个递归的:
第12楼 不得不爱 发表于 2006-10-02 19:58
超级版主 发帖 2,044 积分 5,310 来自 四川南充
数字前面是0系统就认为是八进制,而8八进制里是没有8和9的!因而出错!
[ 联系联盟系统管理团队 - 中国DOS联盟 - 标准版 ]
Sponsored by ifanr Inc | © 2001–2023