elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  [BATCH]Suma y resta números de cualquier longitud
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [BATCH]Suma y resta números de cualquier longitud  (Leído 3,883 veces)
Binary_Death

Desconectado Desconectado

Mensajes: 214



Ver Perfil
[BATCH]Suma y resta números de cualquier longitud
« en: 24 Julio 2012, 05:19 am »

Aquí dos funciones nuevas relacionadas con la suma y la resta. Las otras eran para decimales, estas son para saltarse el límite de 32 bits de precisión que tiene la cmd al operar.

Después, cuando haga funciones para división y multiplicación decimal y corrija todos los bugs de estas funciones, lo unificaré todo en una sola clase para poder trabajar en batch con cualquier número real, con todos los dígitos decimales que uno quiera.

Aquí vienen las funciones:

Código:
:_addx
setlocal enabledelayedexpansion
set "f_s=_%~1" & set "s_s=_%~2" & set "add_str="
set/a cnt=1,car=0
:__loop.a
set "n_1=!f_s:~-%cnt%,1!"
set "n_2=!s_s:~-%cnt%,1!"
if "%n_1%%n_2%" EQU "__" goto :_endadd
if "%n_1%" EQU "_" set/a n_1=0
if "%n_2%" EQU "_" set/a n_2=0
set/a add=%n_1%+%n_2%+%car%,car=0,cnt+=1
if %add% GEQ 10 (
set/a car=1
if "!f_s:~-%cnt%,1!!s_s:~-%cnt%,1!" NEQ "__" (
set "add=%add:~-1%"
))
set "add_str=%add%%add_str%"
goto :__loop.a
:_endadd
call :_filset "%add_str%" "add_str"
endlocal & set "%~3=%add_str%" & exit /b

:_subx
setlocal enabledelayedexpansion
if "%~1" EQU "%~2" set "sub_str=0" & goto :_endsub
call :_filset "%~1" "t_1" & call :_filset "%~2" "t_2"
call :_hst "%t_1%" "%t_2%"
if "%hst%" EQU "%t_2%" set "min=_%~2" & set "sbs=_%~1" & set "s_g=-"
if "%hst%" EQU "%t_1%" set "min=_%~1" & set "sbs=_%~2"
set "sub_str=" & set/a cnt=1,c_s=0,car=0
:__loop.b
set "n_1=!min:~-%cnt%,1!"
set "n_2=!sbs:~-%cnt%,1!"
if "%n_1%%n_2%" EQU "__" goto :_endsub
if "%n_2%" EQU "_" set/a n_2=0
if "%car%" EQU "1" set/a n_2+=1,car=0
if %n_1% LSS %n_2% set/a c_s=10,car=1
set/a sub=%n_1%-%n_2%+%c_s%
set "sub_str=%sub%%sub_str%"
set/a cnt+=1,c_s=0
goto :__loop.b
:_endsub
call :_filset "%sub_str%" "sub_str"
endlocal & set "%~3=%s_g%%sub_str%" & exit /b

:_filset
for /f "tokens=* delims=0" %%_ in ("%~1") do set "%~2=%%_"
if not defined %~2 set/a "%~2=0"
exit /b

:_hst
setlocal enabledelayedexpansion
call :_strlen "%~1" & set/a n[0]=!errorlevel!
call :_strlen "%~2" & set/a n[1]=!errorlevel!
if %n[0]% EQU %n[1]% set "s_0=%~1" & set "s_1=%~2" & goto :_endhst
set/a hst=0,nhst=1
if %n[1]% GTR !n[%hst%]! set/a hst=1,nhst=0
set/a l_0=!n[%hst%]!-!n[%nhst%]!
shift/0 & call set "s_0=%%~%hst%" & call set "s_1=%%~%nhst%"
for /l %%_ in (1,1,%l_0%) do call set "s_1=0!s_1!"
:_endhst
for /f %%_ in ('"(echo:%s_0%&echo:%s_1%)|sort"') do set "hst=%%_"
endlocal & set "hst=%hst%" & exit /b

:_strlen
setlocal
set/a cnt=0
for /f "tokens=* eol=" %%_ in (
'"cmd /u /c echo:%~1|more"'
) do set/a cnt+=1
endlocal & exit /b %cnt%

La sintaxis es:

Código:
call :_addx "sum1" "sum2" "variable_almacén"
call :_subx "min" "sbs" "variable_almacén"

Un saludo, y por favor, cualquier bug que encuentren díganmenlo, que así me ayudarán a mejorar la clase final ;)

PD: Devuelve también, en el caso de la resta, resultados negativos si el substraendo es mayor que el minuendo ;)

EDIT: Bug fixeado.

Un pequeño ejemplo de su uso:

Código:
@Echo Off
more/c<nul
echo:  125504500255796221456988250471037
echo:-        47662554011498822047690014
echo:-------------------------------------
call :_subx "125504500255796221456988250471037" "47662554011498822047690014" "rslt"
echo:  %rslt%
pause>nul & exit

Como podéis ver, estos números son imposibles de operar en batch, pero usando esta función es posible.

Con decimales y con capacidad para manejar números astronómicos, creo que ya no hay excusas para no hacer programas de matemáticas en batch.


« Última modificación: 24 Julio 2012, 09:35 am por Binary_Death » En línea

BatchianoISpyxolo

Desconectado Desconectado

Mensajes: 166


Ver Perfil
Re: [BATCH]Suma y resta números de cualquier longitud
« Respuesta #1 en: 24 Julio 2012, 11:22 am »

Genial binary_death. Trataré de testearlo :)

Yo también estoy implementando el tipo de dato array-fake (unidimensional) aunque voy poquito a poco. Fake porque se basa simplemente en variables estáticas  ;D pero ya va tomando forma.

Hace años un compi mío que también estaba en IH, hizo que batch trabajara con decimales, pero no recuerdo cómo ni qué exactamente... a ver si encuentro el código... :)

A ver si hoy me pongo con el TAD array y lo posteo...

Salud3t3S


En línea

Puede que desees aprender a programar desde 0: www.espascal.es
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Actualizando navegador y suma y resta de registros
PHP
calamardcm 5 3,425 Último mensaje 5 Noviembre 2007, 14:56 pm
por calamardcm
[Batch] Función que suma números positivos mayores a 32 bits. v1.2
Scripting
0x0309 1 4,472 Último mensaje 14 Abril 2009, 23:39 pm
por M a t t
[Com] float v2 (Suma,resta,multiplicacion y division decimal)
Scripting
LauBuru 3 5,363 Último mensaje 4 Julio 2010, 22:11 pm
por LauBuru
[c++] Suma, resta, multiplicacion y division « 1 2 »
Programación C/C++
dani__ 16 63,765 Último mensaje 6 Junio 2013, 03:08 am
por dorkam
Números de longitud variable en C (Numeros muy grandes)
Programación C/C++
AlbertoBSD 0 2,723 Último mensaje 30 Abril 2016, 20:40 pm
por AlbertoBSD
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines