Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 更新bat文件中运行的无符号长和_Batch File - Fatal编程技术网

Batch file 更新bat文件中运行的无符号长和

Batch file 更新bat文件中运行的无符号长和,batch-file,Batch File,在.BAT文件中,有没有一种简单的方法可以求两个数的和>=2*31? 我有一个运行求和,参数%1是现有文件的名称 set sum=4123456789 set fsize=%~z1 我想在总数中加上fsize。不幸的是,fsize(和sum)可能小到0或10千兆字节(%~z1准确地报告>=2*31文件大小) 我知道一个程序可以做到这一点,如果有必要的话,我也会这样做,但我更喜欢添加几行.BAT逻辑。所需的逻辑没有那么复杂。这是一个版本: @echo off setlocal :loop se

在.BAT文件中,有没有一种简单的方法可以求两个数的和>=2*31? 我有一个运行求和,参数%1是现有文件的名称

set sum=4123456789
set fsize=%~z1
我想在总数中加上fsize。不幸的是,fsize(和sum)可能小到0或10千兆字节(%~z1准确地报告>=2*31文件大小)


我知道一个程序可以做到这一点,如果有必要的话,我也会这样做,但我更喜欢添加几行.BAT逻辑。

所需的逻辑没有那么复杂。这是一个版本:

@echo off
setlocal

:loop
set /p "pair=Enter two numbers separated by plus sign: "
if errorlevel 1 goto :EOF

for /F "tokens=1,2 delims=+" %%a in ("%pair%") do set "num1=%%a" & set "num2=%%b"
set "sum="
set "carry=0"
:nextDigit
   set /A sum1=%num1:~-1%+%num2:~-1%+carry
   set "sum=%sum1:~-1%%sum%"
   set /A carry=sum1/10
   set "num1=%num1:~0,-1%"
   if not defined num1 set "num1=0"
   set "num2=%num2:~0,-1%"
   if not defined num2 set "num2=0"
if "%carry%%num1%%num2%" neq "000" goto nextDigit

echo The sum is: %sum%
goto loop

我认为最简单的方法是将总和分成两部分——整数和分数千兆(100000000的倍数),分别添加各自的部分,然后重新组合。请参见以下示例脚本,其中包含大量解释性注释:

@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
rem//初始化变量:
设置/A“GIGASUM=0,FRACSUM=0”
:循环
rem//Get命令行参数:
转移
设置“NUM=%~0”
如果未定义NUM goto:NEXT
rem//检查编号是否有效:
(对于/F“delims=0123456789”%%N in(“%NUM%”)do rem/)&&(
回显错误:遇到非数字字符!
退出/B 1
)
rem//将数字分成两部分,整数和小数千兆:
设置“NUM=000000000%NUM%”
设置“GIGA=%NUM:~,-9%”和设置“FRAC=%NUM:~-9%”
rem//从整数Gigas中删除前导零:
对于/F“令牌=*delims=0”%%N in(“%GIGA%”)请设置“GIGA=%%N”
rem//求和分数千兆并确定进位:
设置/A“分数总和+=(1%分数%-100000000)”
设置“进位=%FRACSUM:~,-9%”并设置“FRACSUM=000000000%FRACSUM%”
设置“FRACSUM=%FRACSUM:~-9%”
rem//求整数千兆和进位:
设置/A“千兆总和+=千兆进位”
rem//循环回下一个summand:
转到:循环
:下一个
rem//删除前导零:
对于/F“令牌=*delims=0”%%N in(“%GIGASUM%%FRACSUM%”)设置“总和=%%N”
如果未定义总和,则设置“总和=0”
rem//返回结果和:
回显%SUM%
端部
退出/B

最大可能的总和为
231*109–1=214748364799999999
,未检测到溢出。

批处理本身仅支持32位数字,但您可以编写自己的数学库。我只想到了个位数的方法,这似乎太多了——你们让我走上了正轨。现在我通过:
set/ash=sl=0
I更新sum通过:
set/ash+=%fsize:~0,-9%+0,sl+=%fsize:~-9%,sh+=sl/100000000,sl%=100000000
任何时候的和都是sl(如果sh是0)或sh与sl相连(在用任何必要的前导零填充sl到长度9之后).
sl+=%fsize:~-9%
如果保留前导零,则会导致问题,因为前导零表示八进制数(请参见
set/?
);您可以通过
sl+=1%fsize:~-9%%%100000000
来避免这种情况……谢谢。。。错过了!我曾多次被“零导联触发八进制”错误所困扰,并对stackoverflow上的任何语言都存在“功能”这一事实表示哀叹。有人真正使用八进制吗?好吧,我承认我表现出了我的偏见和有限的背景(以及挫折感)。我想几乎所有曾经使用过
set/A
的人都掉进了八进制陷阱。。。我希望八进制数有一个像
0o
这样的前缀,这是显而易见的,但是将
0
定义为前缀对我来说太愚蠢了…
sl+=1%fsize:~-9%%%100000000
在%fsize%小于9位时会产生不正确的结果。我通过将
sl
限制为仅保留8位,并将求和步骤更改为
set/ash+=%fsize:~0,-8%+(sl+=1%fsize:~-8%%%(2%fsize:~-8%-1%fsize:~-8%)/100000000,sl%%=100000000