中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: [原创]批处理计算N次方根 上一主题 | 下一主题
qinchun36
高级用户

据说是李先生


积分 609
发帖 400
注册 2008-4-23
状态 离线
『楼 主』:  [原创]批处理计算N次方根

因为批处理支持的数字大小有限,并且本身不支持小数,所以计算得到的精确度可能不是太高。
这是一个牛顿迭代法的实现,相关内容请自己去看。
两个“函数”中有几行注释掉的 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 ===


   此帖被 +7 点积分      点击查看详情   
评分人:【 523066680 分数: +5  时间:2010-8-29 20:24
评分人:【 WANKOILZ 分数: +2  时间:2010-8-29 21:34


2010-8-29 18:11
查看资料  发送邮件  发短消息 网志  OICQ (182484135)  编辑帖子  回复  引用回复
523066680
银牌会员

SuperCleaner


积分 2362
发帖 1133
注册 2008-2-2
状态 离线
『第 2 楼』:  

恩,虽然对批处理已经没有以前的feel了,既然路过,还是加了个油!



综合型编程论坛

我的作品索引
  
2010-8-29 20:23
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (523066680)  编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: