| @set 保留小数位数=25 |
| |
| |
| @set 精度=0.0000001 |
| |
| |
| |
| @echo off |
| pushd "%~dp0" |
| setlocal enabledelayedexpansion |
| title 老刘编写——纯批处理正弦函数计算器 |
| echo 正弦函数计算部分由@老刘编写。 |
| echo 浮点数四则运算由@MHL编写,在此表示感谢。 |
| echo. |
| echo 计算原理: |
| echo 将输入的弧度诱导到[0,2*pi]之内。 |
| echo sin通过公式sin^(x^)=3sin^(x/3^)-4[sin^(x/3^)]^^3放缩为更小的sin角来计算。 |
| echo 而sin^(x^)与x在^|x^|^<0.1时相差不大,故可用x替代。 |
| echo 目前设定的精度要求为^|x^|^<!精度!时使用x替代sin^(x^)。 |
| echo. |
| echo 注意事项: |
| echo 放缩、累加过程通过递归实现,受批处理递归层数限制,可能溢出。 |
| echo 虽然改成迭代写法可以提高效率,但是真的懒得改了(逃)。 |
| echo 目前设定为保留!保留小数位数!位小数,可自行修改。 |
| echo. |
| echo 使用方法: |
| echo 不支持表达式,请分步计算。 |
| echo 计算结果会自动放入剪辑版,以供粘贴。 |
| echo 内建常量:%%pi%% |
| echo 正弦计算:输入“sin 弧度”并回车。 |
| echo 四则计算:输入“[add/multiply/divide] 数1 数2”并回车。 |
| echo. |
| echo. |
| |
| echo 关闭句柄1(标准输出)。>nul 3>nul |
| |
| set /a 保留小数位数+=1 |
| set pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 |
| call :_round pi !保留小数位数! |
| call "multiply" !pi! 2 |
| set _2pi=!errorlevel! |
| call :_round _2pi !保留小数位数! |
| |
| :loop |
| set /p "command=>>> ">con |
| call :!command! |
| echo.>con |
| goto loop |
| |
| |
| :add |
| call "plus&minus" %1 %2 |
| echo 计算结果:!errorlevel! >con |
| set /p "=!errorlevel!"<nul | clip |
| goto :eof |
| |
| :divide |
| call "divide" %1 %2 %保留小数位数% |
| echo 计算结果:!errorlevel! >con |
| set /p "=!errorlevel!"<nul | clip |
| goto :eof |
| |
| :multiply |
| call "multiply" %1 %2 |
| echo 计算结果:!errorlevel! >con |
| set /p "=!errorlevel!"<nul | clip |
| goto :eof |
| |
| :sin |
| call :_sin %1 |
| echo 计算结果:!errorlevel! >con |
| set /p "=!errorlevel!"<nul | clip |
| goto :eof |
| |
| :_sin |
| setlocal |
| set number=%1 |
| :__sin_loop |
| call :_isBigger !number! !_2pi! |
| if !errorlevel! == true ( |
| call "plus&minus" !number! -!_2pi! |
| set number=!errorlevel! |
| goto __sin_loop |
| ) |
| call :_isBigger !number! 0 |
| if !errorlevel! == false ( |
| |
| call :_sin !number:~1! |
| set dest=!errorlevel! |
| call :_isBigger !dest! 0 |
| if !errorlevel! == true ( |
| set dest=-!dest! |
| ) |
| ) else ( |
| call :_isBigger !number! !精度! |
| if !errorlevel! == false ( |
| |
| set dest=!number! |
| ) else ( |
| |
| call "divide" !number! 3 %保留小数位数% |
| call :_sin !errorlevel! |
| set sinNumberDivide3=!errorlevel! |
| call "multiply" !sinNumberDivide3! 3 |
| call :_round errorlevel %保留小数位数% |
| set destPart1=!errorlevel! |
| |
| >con set sinNumberDivide3 |
| call "multiply" !sinNumberDivide3! !sinNumberDivide3! |
| call :_round errorlevel %保留小数位数% |
| call "multiply" !errorlevel! !sinNumberDivide3! |
| call :_round errorlevel %保留小数位数% |
| call "multiply" !errorlevel! 4 |
| call :_round errorlevel %保留小数位数% |
| set destPart2=!errorlevel! |
| >con set destPart2 |
| |
| rem destPart2必定是正数。 |
| call "plus&minus" !destPart1! -!destPart2! |
| set dest=!errorlevel! |
| call :_round dest %保留小数位数% |
| ) |
| ) |
| for %%a in (!dest!) do endlocal&set errorlevel=%%a |
| goto :eof |
| |
| :_isBigger number1 number2 |
| |
| setlocal |
| set number2=%2 |
| if "!number2:~,1!" == "-" ( |
| set "number2=+!number2:~1!" |
| ) else ( |
| set "number2=-!number2!" |
| ) |
| |
| call "plus&minus" %1 !number2! |
| if "!errorlevel:~,1!" == "-" ( |
| set dest=false |
| ) else ( |
| set dest=true |
| ) |
| for %%a in (!dest!) do endlocal&set errorlevel=%%a |
| |
| |
| goto :eof |
| |
| :_round 四舍五入函数(提高精度用) 变量 保留小数位数-1 |
| setlocal |
| |
| rem 备份%1,使其支持处理errorlevel。 |
| set number=!%1! |
| |
| rem 若无小数部分,直接返回。 |
| if "!number!" equ "!number:.=!" goto :eof |
| |
| rem 若位数比保留位数少,直接返回。 |
| set demicalPart=!number:*.=! |
| set /a __round_tmp=%2-1 |
| for %%a in (!__round_tmp!) do ( |
| if "!demicalPart:~%%a,1!" equ "" goto :eof |
| ) |
| |
| rem 从最后一位向前四舍五入到指定的位数。 |
| set carry=0 |
| :__round_loop |
| set /a lastNum=!demicalPart:~-1!+carry |
| set carry=0 |
| if !lastNum! geq 5 set carry=1 |
| :__round_jumpin |
| if "!demicalPart:~%2,1!" equ "" ( |
| set demicalPart=!demicalPart:~,-1! |
| set /a lastNum=!demicalPart:~-1!+carry |
| set carry=0 |
| goto __round_loop2 |
| ) |
| set demicalPart=!demicalPart:~,-1! |
| goto __round_loop |
| |
| |
| rem 若出现9+1,则继续进位。 |
| :__round_loop2 |
| if !lastNum! equ 10 ( |
| set demicalPart=!demicalPart:~,-1! |
| set /a lastNum=!demicalPart:~-1!+1 |
| if "!demicalPart!" neq "" ( |
| goto __round_loop2 |
| ) else ( |
| set demicalPart=0 |
| set carry=1 |
| ) |
| ) else ( |
| set demicalPart=!demicalPart:~,-1!!lastNum! |
| ) |
| call "plus&minus" !number! !carry! |
| for /f "tokens=1,3 delims=. " %%a in ("!errorlevel! !demicalPart!") do endlocal&set %1=%%a.%%b |
| |
| rem echo 计算结果:!%1! >con |
| |
| goto :eofCOPY |