如何使用批处理脚本查找大型因子

时间:2013-12-20 15:49:02

标签: batch-file factorial

@echo off
if %1.==. ( echo Missing parameter! Try passing the number as a parameter     like   'factorial   10' without the quotes.
goto end )
setlocal enabledelayedexpansion
set /a count=0
set /a temp=0
set /a digits=1
set /a array1=1
for /L %%i IN (2,1,%1) do (
set /a temp=0
for /L %%j IN ( 1,1,!digits! ) do (
set /a temp=!temp!+!array%%j!*%%i
set /a array%%j=!temp!%%10
set /a temp=!temp!/10   ) 

set /a index=!digits!+1

for /L %%v IN (!index!,1,!index! ) do (
if !temp! NEQ 0 (
set /a array!index!=!temp!%%10
set /a temp/=10
set /a index+=1 ))
set /a digits=!index!-1)
for /l %%v IN ( !digits!,-1,1 ) do set array=!array!!array%%v!
echo !array!
echo Total # of decimal digits = !digits!
:end
pause

这是我到目前为止所得到的。 10岁以下相当稳定!但是一旦我达到15或20,它就会错过几个数字。

我的编辑....

@echo off
if %1.==. ( echo Missing parameter! Try passing the number as a parameter  like   'factorial   10' without the quotes.
goto end )
setlocal enabledelayedexpansion
set /a count=0
set /a temp=0
set /a digits=1
set /a array1=1
for /L %%i IN (2,1,%1) do (
set /a temp=0
for /L %%j IN ( 1,1,!digits! ) do (
set /a temp=!temp!+!array%%j!*%%i
set /a array%%j=!temp!%%10
set /a temp=!temp!/10   ) 

for /l %%v IN ( 1,1,30 ) do (
if !temp! neq 0 (
set /a digits+=1
set /a array!digits!=!temp!%%10
set /a temp=!temp!/10
)))
for /l %%v IN ( !digits!,-1,1 ) do set array=!array!!array%%v!
echo !array!
echo Total # of decimal digits = !digits!
:end
pause

现在我强迫最后一个内循环运行30次,尽管temp在此之前已经为零。有没有办法写一个类似于以下c代码的片段     而(临时)     {/ 代码在这里 /}

只有当temp不为零时才执行。

对于批次中变量的大小,是否存在任何限制? 我知道批量调试计算程序是一个痛苦的 * ,我只是想用我知道的所有编程语言编写代码,这样我就可以比较它们的速度了。有人可以指出我在这里做错了什么。

编辑........ 22/12/13

@echo off
if %1.==. ( echo Missing parameter! Try passing the number as a parameter like   'factorial   10' without the quotes.
goto end )
setlocal enabledelayedexpansion

set /a count=0
set /a tempo=0
set /a digits=1
set /a array1=1

for /f "tokens=1-4 delims=:.," %%a IN ("%time%") do (     
set /a "start=(((%%a*60)+1%%b %% 100)*60+1%%c %%100)*100+1%%d %% 100"
)

for /L %%i IN (2,1,%1) do (
set /a tempo=0
for /L %%j IN ( 1,1,!digits! ) do (
set /a tempo=!tempo!+!array%%j!*%%i
set /a array%%j=!tempo!%%10000
set /a tempo=!tempo!/10000   ) 

for /l %%v IN (1,1,2) do (
if !tempo! neq 0 (
set /a digits+=1
    set /a array!digits!=tempo%%10000
set /a tempo=tempo/10000
))
)

for /l %%v IN ( !digits!,-1,1 ) do set array=!array!!array%%v!
echo !array!  
echo Total # of decimal digits = !digits!

for /f "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /a "end=(((%%a*60)+1%%b %% 100)*60+1%%c %%100)*100+1%%d %% 100"
)

set /a elapsedcs=end-start
set /a elapseds=elapsedcs/100
set /a elapsedcs=elapsedcs%%100
echo %elapseds%.%elapsedcs% seconds
:end
rem label should never be the last statement

这是你的意思吗?

3 个答案:

答案 0 :(得分:3)

为了在Batch中对Big numbers进行快速算术运算,必须将Bignum拆分为数字组,这些数字可通过{{1}的32位操作进行管理命令。最大32位有符号整数是2147483647,因此可以乘以这种方式的最大数字组是4,因为5位数(99999 x 99999)超过了最大数。必须从右到左实现加法和乘法翻译" carry"到左边的下一组。减法和除法必须从左到右翻译一个"借用"到右边的下一组。下面的批处理文件使用此方法将Bignum连续乘以4位数因子,因此最多可以计算9999!只要包含4位数组的所有变量都适合环境的64 MB size limit(查找" 65,536KB最大大小""设置环境变量")。结果直接输出到屏幕,以避免一个Batch变量的8192位数限制。

编辑:我稍微修改了程序,以便更快地运行并获得结果中的位数。

set /A

答案 1 :(得分:2)

我必须重新读取代码才能看到它在做什么。尼斯。

您的代码必须面对三个限制。

1 - 在内部%%j%%v循环中,buffer用于乘以%% i中的当前值,您将面对Magoo指示的限制。您无法使用值大于2 ^ 31的set /a进行操作。由于array中的值限制为0-9,这意味着此限制不允许您计算大于214748364(aprox)的数字的阶乘

2 - 环境变量的大小有限制。它不能超过32767个字符。当您将数字连接到控制台(下一个限制是相关的)时,这会限制您使用低于9273(aprox)的数字的阶乘。

3 - cmd可以处理的行的长度有限制。它是8191个字符。这不会限制您的计算,但您不能使用连接变量的方法来表示数字。如果方法未更改,则会将您限制为低于2727(aprox)的数字因子。

答案 2 :(得分:0)

批处理仅限于有符号的32位整数。

BTW - 不要将temptmp用作用户变量。它由系统设置为指向存储临时文件的目录的指针。