Batch不能正确地计算方程



我最近尝试在不使用外部命令或工具的情况下批量编写一个程序,计算任何实数(而不是负数)的平方根,该程序基于可以在这里找到的算法:Link1

编辑:我修复了大部分问题,但仍有一个轻微的未被我发现的问题。

请运行这个"调试模式"代码:Link2并测试输出数字15625和精度3。

为了使代码正确,调试代码必须显示:

- finalpart: 1
2
adder: 56
- finalpart: 44
3
adder: 25
- finalpart: 1225
4
adder: 0
Answer: 125

对不起。如果你想让我们检查你的代码寻找错误,我不能帮助你。您的代码很长,没有一个描述性注释,并且几个变量名称令人困惑,容易导致编辑错误。我看了你的维基百科文章的链接,这个方法对我来说似乎很有趣,但是当我将所描述的方法与你的程序进行比较时,代码似乎不必要地复杂,所以我决定编写我自己的版本;如果这不是你想要的,我很抱歉。

在这个程序中,精度被设置为输入数字的小数点数/2,但一个非常简单的修改将允许将其设置为一个固定的数字。我用多个数字测试了这个程序,并且工作正常。

@echo off
setlocal
:nextNumber
   set "number="
   set /P "number=Number:      "
   if not defined number goto :EOF
   call :SquareRoot %number% sqrt=
   echo Square root: %sqrt%
   echo/
goto nextNumber

:SquareRoot number result=
setlocal EnableDelayedExpansion
rem Separate the number in aligned blocks of 2 digits each
for /F "tokens=1,2 delims=." %%a in ("%1") do set "int=%%a" & set "frac=%%b"
set /A i=11, f=10
:nextInt
   if not defined int goto nextFrac
   set /A i-=1
   set "block[%i%]=%int:~-2%"
   set "int=%int:~0,-2%"
goto nextInt
:nextFrac
   if not defined frac goto checkLastBlock
   set /A f+=1
   set "block[%f%]=%frac:~0,2%"
   set "frac=%frac:~2%"
goto nextFrac
:checkLastBlock
if %f% gtr 10 if "!block[%f%]:~1!" equ "" set "block[%f%]=!block[%f%]!0"
rem Get square root of first block: digit between 0 and 9
set /A num=block[%i%], iP1=i+1, addZeros=0
for /L %%r in (0,1,9) do (
   set /A r2=%%r*%%r
   if !r2! leq %num% set /A sqrt=%%r, remainder=num-r2
)
rem Get square root of next blocks
for /L %%i in (%iP1%,1,%f%) do (
   set /A remainder1=remainder*10+!block[%%i]:~0,1!, remainder2=remainder*100+1!block[%%i]!-100, sqrtT2=sqrt*2
   if !sqrtT2! equ 0 (
      rem The number started with zeros: no sqrt yet
      set "sqrt="
      set /A addZeros+=1
      for /L %%r in (0,1,9) do (
         set /A r2=%%r*%%r
         if !r2! leq !remainder2! set /A nextDigit=%%r, remainder=remainder2-r2
      )
   ) else if !remainder1! lss !sqrtT2! (
      rem There is no sqrt for this block
      set /A nextDigit=0, remainder=remainder2
   ) else (
      set /A nextDigit=remainder1/sqrtT2, test=sqrtT2*10+nextDigit, this=test*nextDigit
      if !this! gtr !remainder2! (
         rem Next digit is too large: decrease it
         set /A "times=(this-remainder2)/test+1"
         for /L %%t in (1,1,!times!) do if !this! gtr !remainder2! (
            set /A nextDigit-=1, test=sqrtT2*10+nextDigit, this=test*nextDigit
         )
      )
      set /A remainder=remainder2-this
   )
   set "sqrt=!sqrt!!nextDigit!"
)
for /L %%i in (1,1,%addZeros%) do set "sqrt=0!sqrt!"
set /A point=11-i
set "sqrt=!sqrt:~0,%point%!.!sqrt:~%point%!"
endlocal & set "%2=%sqrt%"
exit /B

输出示例:

Number:      15625.000000
Square root: 125.000
Number:      625
Square root: 25.
Number:      64
Square root: 8.
Number:      9
Square root: 3.
Number:      0.25
Square root: 0.5
Number:      987654321987654321
Square root: 993807990.
Number:      1234567890123456789
Square root: 1111111106.
Number:      2.000000000000000000
Square root: 1.414213562

这段代码显示了平方根的小数点后30。

here is My Way:

@echo off
title SQR
set /p x=PLS Enter Your Number = 
echo.
echo Wscript.Echo (FormatNumber(SQR(Wscript.Arguments(0)),30))>Q.vbs
cscript //nologo Q.vbs %x% & DEL "Q.vbs"
PAUSE>NUL

最新更新