中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-07-31 16:24
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [共同参与][挑战思路][批处理处理浮点运算] 精华I 查看 43,147 回复 136
31 发表于 2006-10-06 00:38 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
32 发表于 2006-10-06 01:11 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
10楼代码错误!
请输入运算数一:132165.134646454
请输入运算数二:132654.6546546
-2
132165.134646454+132654.6546546=-2?
33 发表于 2006-10-06 03:38 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
10楼已经说明, 小数位最多可运算8位数. 而你的小数部分为9位, 溢出了...

发现15楼的代码有几点缺陷; 运算错误, 多加了1. 零的问题上没有考虑完全(111+111=223), (0.23+1.08=2.31)...

版主还需要改进代码, 具体10楼的代码和4楼的代码都用最前位添1的办法解决了(这也是为什么10楼和4楼的代码小数部分只能运算8位的原因了).


关于10楼(整数浮点数合并运算)代码的注意事项:

整数位最多可运算8位数, 小数位最多可运算8位数.
小数位整数位加起来最多可运算9位数
否则会溢出或为无效数字...


[ Last edited by pengfei on 2006-10-6 at 04:05 ]
34 发表于 2006-10-06 03:41 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
另外4楼的代码经过改进已经可以通用了, 甚至比10楼的代码更具优越性.

具体表现在它的运算范围更大, 小数整数最多可以运算17位. 代码更简洁, 容错性更好!

刚写出来, 可能还有些问题还没有考虑进去. 期待大家进行全面测试...
35 发表于 2006-10-06 07:43 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
我刚才检查了下,原来是把set/a n1+=1打成了set n1+=1,所以出错。
15楼已经更新!小数最多可以9位,整数最多可以运算9位,支持A 136.987 236这种输入和输入A后按照提示输入!
欢迎大家测试...

[ Last edited by qwe1234567 on 2006-10-7 at 03:45 ]
36 发表于 2006-10-06 07:50 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
4楼上面的代码有错误,整数前有0就出错,小数后位对不齐!
a 008.64 36.6
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。
.70
请按任意键继续 . . .
a 8.64 36.6
44.70

[ Last edited by qwe1234567 on 2006-10-6 at 07:54 ]
37 发表于 2006-10-06 09:52 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
版主这种a 008.64属于错误输入的范筹吧, 这个我是没考虑过, 还是测试浮点运算可能出现的各种情况吧! 36楼测试的错误我并没有发现...

版主说的前面有0就出错, 肯怕不会吧, 取位循环去零法可以去最高位所有的零.

而小数后位对不齐, 这是格式输出的问题, 也没有考虑, 代码只作为测试运算结果的对与否. 如果坚持要格式输出的话也可以考虑加入相应代码.

欢迎大家测试4楼和10楼代码的运算缺陷...

[ Last edited by pengfei on 2006-10-6 at 10:16 ]
38 发表于 2006-10-06 19:29 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
就是我把4楼上面的代码(输入是%1和%2的那个文件)写入A.BAT文件里,然后在CMD里输入:
a 008.64 36.6
无效数字。数字常数只能是十进制(17),十六位进制(0x11)或
八进制(021)。
.70
请按任意键继续 . . .
a 8.64 36.6
44.70
39 发表于 2006-10-06 19:42 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
呵呵~ 我那段代码只限于在批处理中运算, 不能接受变量%1, %2的输入. 版主应该一看就知道.

恭喜你的代码已经加入取位循环去零法和小数位前添1运算代码, 解决了这一系列问题. 还增加了在CMD下使用的代码^_^

目前第4楼, 第10楼, 以及qwe1234567版主的代码测试一切正常...
40 发表于 2006-10-06 23:34 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
那请问4楼上的里的%1和%2是接受哪儿的变量?(下面的代码是你4楼上面的,请看!)
@echo off
setlocal enabledelayedexpansion
for %%a in (%1,%2) do (
set /a num+=1
for /f "tokens=1,2 delims=." %%i in ("%%a") do (
if "!num!"=="1" (set one=%%i) else (set one_=%%i)
if "!num!"=="1" (set two=%%j) else (set two_=%%j)
)
)
set /a integer=%one%+%one_%
set /a decimal=%two%+%two_%
if %decimal:~0,1% lss %two:~0,1% (
set /a integer=%integer%+1
set /a decimal=%decimal:~1%
) else (
if %decimal:~0,1% lss %two_:~0,1% (
set /a integer=%integer%+1
set /a decimal=%decimal:~1%
)
)
echo %integer%.%decimal%
pause

里的%1和%2是接受哪儿的变量?
41 发表于 2006-10-06 23:35 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
这一段脚本是最初的, 很多问题都没解决, 4楼下面还有一段呢?
42 发表于 2006-10-07 03:08 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
43 发表于 2006-10-08 00:13 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
新思路计算方法:
计算前小数位首位自动去0、尾数自动去0,整数首位自动去0,最大的得数是:2147483647.2147483647(小数位最大得数是.2147483647、整数最大得数是.2147483647)
如果加数的小数位首位都有N个以上的0,小数位的位数可以多到N+9个以上!
欢迎大家测试!
321.00000000065496546+13.000000000046541346=334.000000000701506806
321.1105496546+13.1041541346=334.2147037892
@echo off
if not %1*==* (set number=%1&set number_=%2&goto bj)
set /p number=请输入运算数一:
set /p number_=请输入运算数二:
:bj
echo %number% | find "." >nul || set number=%number%.0
echo %number_% | find "." >nul || set number_=%number_%.0
if %number:~0,1%==. set number=0%number%
if %number_:~0,1%==. set number_=0%number_%
if "%number:~-1%"=="." set number=%number%0
if "%number_:~-1%"=="." set number_=%number_%0
setlocal enabledelayedexpansion
for /f "tokens=1-4 delims=." %%a in ("%number%.%number_%") do (
set one=%%a
set two=%%b
set one_=%%c
set two_=%%d
)
call :go %two%
set two=%ls%
set num1=%wish%
call :go %two_%
set two_=%ls%
set num2=%wish%
if %num1% lss %num2% (
set note=%num2%
set /a result=%num2%-%num1%
call :fine !result! %two%
set two=!incept!
) else (
set note=%num1%
set /a result=%num1%-%num2%
call :fine !result! %two_%
set two_=!incept!
)
:1
if "!one:~0,1!"=="0" set one=%one:~1%&&goto 1
:11
if "!two:~0,1!"=="0" set two=%two:~1%&&goto 11
if %two%*==* set two=0
:2
if "!one_:~0,1!"=="0" set one_=!one_:~1!&&goto 2
:22
if "!two_:~0,1!"=="0" set two_=!two_:~1!&&goto 22
if %two_%*==* set two_=0
set/a num2=%two%+%two_%
set/a n1=0!num2:~0,-%note%!
if %num2%==0 set num2=&&goto go3
set num2=!num2:~-%note%!
set ls=%num2%
:go1
if not %ls%*==* (
set ls=!ls:~1!
set/a go+=1
goto go1
)
:go2
if not %go%*==%note%* (
set/a go+=1
set num2=0%num2%
goto go2
)
:go3
set /a num1=%one%+%one_%+%n1%
:3
if !num2:~-1!==0 set num2=!num2:~0,-1!&&goto 3
if %num2%*==* (echo %number%+%number_%=%num1%) ELSE echo %number%+%number_%=%num1%.%num2%
PAUSE
goto :eof

:go
set remove=%1
set wish=0
:q0
if %remove:~-1%*==0* (
set remove=!remove:~0,-1!
goto q0
)
set ls=%remove%
:go_
if not %remove%*==* (
set /a wish+=1
set remove=!remove:~1!
goto go_
)
goto :eof
:fine
set take=%1
set incept=%2
:fine_
if not "%take%"=="0" (
set/a take-=1
set incept=!incept!0
goto fine_
)
goto :eof


[ Last edited by qwe1234567 on 2006-10-8 at 05:20 ]
44 发表于 2006-10-08 04:47 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
看了一下版主的代码有两点改进:
1. 在读取两个运算数的整数小数部分时, 你放到一起的方法提取. 思路不错^_^
2. 小数部分首位为零就去零运算. (这里小数部分前置零是不影响运算的, 这点和整数运算一样)

这段代码虽然发现小数运算暂时没有出错, 但却不能运算整数了(原因在于去小数最前位零, 如果只有一个零就没有运算数了. 甚至以后的几句代码都会出错).这里个问题倒可以解决.

以前觉得小数前全部添1简单省事, 但却只能运算8位. 呵呵~ 还是觉得更大的运算范围更重要, 代码正在更新中...
45 发表于 2006-10-08 05:22 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
积分 5,310
发帖 2,044
注册 2005-09-26 12:00
20年会员
UID 42843
性别 男
来自 四川南充
状态 离线
去小数最前位零, 如果只有一个零就没有运算数了. 甚至以后的几句代码都会出错的问题已经解决。更新在43楼。
欢迎大家测试!
论坛跳转: