中国DOS联盟

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

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

中国DOS联盟论坛
现在时间是 2026-07-08 04:22
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]批处理计算N次方根 查看 1,063 回复 1
楼 主 [原创]批处理计算N次方根 发表于 2010-08-29 18:11 ·  中国 北京 联通
高级用户
★★★
据说是李先生
积分 609
发帖 400
注册 2008-04-23 15:55
18年会员
UID 116706
性别 男
状态 离线
因为批处理支持的数字大小有限,并且本身不支持小数,所以计算得到的精确度可能不是太高。
这是一个牛顿迭代法的实现,相关内容请自己去看。
两个“函数”中有几行注释掉的 echo 语句,打开的话可以看见计算过程。

NewtonIteration.bat ver1.0

@echo off
:: 由于命令行只能使用整数,且最大位 32 位
:: 因此这两个方法能计算的数的绝对值最大值不超过 2147483648
:: 同时计算比较高的次数时,误差会比较大
:: 计算的结果是精确值在与结果相同的精度下截取的前几位
call :NewtonIterationFloat 170.36 2 pfg
call :NewtonIterationInteger 987654321 7 root7
echo === 测试 170.36 的平方根是 %pfg% ===
echo === 测试 987654321 的七次方根的整数部分是 %root7% ===
pause
goto :EOF


REM (C)2010 qinchun36 牛顿迭代法求 N 次方根
REM 求一个浮点数 %1 的 %2 次方根的近似值
REM 并将结果赋值到变量名 %3 中(没有则直接显示结果)
REM 需要调用 :NewtonIterationInteger
:NewtonIterationFloat
REM 系统能接受的最大数值及其长度
set /a _$MAX_NUMBER=2147483648
set /a _$MAX_LENGTH=10
set _$number=%1
set /a _$exp=%2
set "_$num=%_$number:.=%0000000000"
for /f "tokens=1,2" %%a in ("%_$number:.= %") do set /a "_$nD=%%a,_$nF=%%b" 2>nul
set /a _$lD=0,_$lF=0
for /l %%a in (0,1,%_$MAX_LENGTH%) do call set /a "_$temp=%%_$nD:~%%a,1%%" 2>nul && set /a _$lD+=1
for /l %%a in (0,1,%_$MAX_LENGTH%) do call set /a "_$temp=%%_$nF:~%%a,1%%" 2>nul && set /a _$lF+=1
set /a _$lR=_$MAX_LENGTH-_$lD,_$lM=_$lR/_$exp,_$lA=_$lD+_$lM*_$exp
call set /a _$num=%%_$num:~0,%_$lA%%%
if %_$num% geq %_$MAX_NUMBER% (
set /a _$lM-=1,_$lA=_$lD+_$lM*_$exp
set "_$num=%_$number:.=%"
call set /a _$num=%%_$num:~0,%_$lA%%%
)
if %_$lM% equ 0 (
call set _$number2=%%_$num:~0,%_$lD%%%
) else (
call set _$number2=%%_$num:~0,%_$lD%%%.%%_$num:~%_$lD%%%
)
::echo 数字 %_$number% 的可计算值为 %_$number2%
call :NewtonIterationInteger %_$num% %_$exp% _$rs2
if %_$lM% equ 0 (
call set "_$rs=%_$rs2%"
) else (
call set "_$rs=%%_$rs2:~0,-%_$lM%%%.%%_$rs2:~-%_$lM%%%"
)
::echo 将 %_$rs2% 的小数点向左移 %_$lM% 位得到结果 %_$rs%
set "%3=%_$rs%" 2>nul||echo.%_$rs%
goto>nul 2>&1
REM === End of :NewtonIterationFloat ===


REM (C)2010 qinchun36 牛顿迭代法求 N 次方根
REM 求一个整数 %1 的 %2 次方根的整数部分
REM 并将结果赋值到变量名 %3 中(没有则直接显示结果)
:NewtonIterationInteger
set /a $x=%1,$n=%2,$n1=$n-1,$$=0,$c=0
set "$y="
for /l %%i in (0,%$n%,10) do call set "$y=%%$y%%%%$x:~%%i,1%%"
::echo 整数 %$x% 的 %$n% 次方根预测值 %$y%
:_NewtonIterationInteger_loop
if %$y% neq %$$% (
set /a $c+=1,$$=$y,$y=$x
for /l %%i in (1,1,%$n1%) do set /a $y/=$$
set /a $y+=$n1*$$,$y/=$n
goto :_NewtonIterationInteger_loop
)
::echo 用牛顿迭代法迭代 %$c% 次后得到近似值 %$$%
set "%3=%$$%" 2>nul||echo.%$$%
goto>nul 2>&1
REM === End of :NewtonIterationInteger ===

本帖最近评分记录 (共 2 条) 点击查看详情
评分人分数时间
523066680 +5 2010-08-29 20:24
WANKOILZ +2 2010-08-29 21:34
2 发表于 2010-08-29 20:23 ·  中国 广东 佛山 电信
银牌会员
★★★★
SuperCleaner
积分 2,362
发帖 1,133
注册 2008-02-02 21:36
18年会员
UID 110072
性别 男
状态 离线
恩,虽然对批处理已经没有以前的feel了,既然路过,还是加了个油!
论坛跳转: