Multiplicación y división con decimales

Si bien ayer expuse un conversor de Hexadecimal a decimal, el objetivo final no es más que un conversor de Decimal a Hexadecimal.
Dicho objetivo no se nos plantea tan complicado usando cualquier lenguaje de programación, pero, como todos sabemos, Batch no es un lenguaje de programación y esto nos trae ciertos problemas, los más dignos de destacar creo que son la inexistencia de la función Len y la discapacidad de Batch frente a operaciones matemáticas con decimales.

Si señores, leen bien, batch es incapaz de sumar dos números decimales provocando el error tan conocido de: ' Falta Operador '.
Para solucionar esto, los programadores hemos creado códigos que se adaptan a la necesidad del proyecto final. E encontrado varios códigos en la red sobre Multiplicaciones y Divisiones con decimales en batch (que son operaciones necesarias para convertir números decimales a hexadecimales) pero como ninguno de ellos me acababa de convencer (o bien la lógica de programación era muy confusa, o simplemente no daba el resultado esperado, decidí crear mis dos propias funciones que pasaré a explicar a continuación:

Multiplicación con decimales



Se me pasó por la cabeza crear un code que cumpliera con la multiplicación con decimales en los 2 niveles (nivel 1: 2,12*2 nivel 2: 2,12*2,1) el caso es que tras pensar un rato no llegué a una conclusión lógica de como efectuar una operación de nivel 2 y como no era de vital necesidad para mi objetivo me decanté por multiplicaciones de nivel 1.

Teniendo como ejemplo: 2,20*6, el proceso empieza por separar las 2 partes de la variable con decimales a partir de la ',' (part1=2 part2=20. Esas dos partes se multiplican por el multiplicador (2*6 y 20*6).
A la segunda parte se le corre la coma según el número de decimales (en este caso 1,20), para ello hace falta separar la variable en dos partes mas (p1 y p2) donde la primera parte es la parte entera y la segunda la parte decimal.
Para finalizar se suma la parte 1 de la segunda separación (p1) a la parte 1 de la primera (parte1), dándonos como resultado 13,2.

División con Decimales



Para la división con decimales solo decir que el método me sorprendió y no es originalmente mío (lo encontré en la red no recuerdo donde...), simplemente intenté codearlo de una forma más clara y de acuerdo a mis necesidades.

El proceso es más sencillo y repetitivo, empezamos dividiendo el dividendo por el divisor y, como batch solo devuelve enteros, buscamos el resto. Con esta acción ya tenemos la parte entera, solo nos falta la decimal.

Para la parte decimal empezamos comprobando que el resto no sea 0, después de hacer eso solo nos encargamos de dividir el resto anterior (agregando un al final 0) para obtener el decimal y de buscar el MOD (resto) del resto anterior (agregando también un 0) para obtener el siguiente decimal, y así hasta que de 0.

Pueden hacer la comprobación con este mismo ejemplo: 1711*16 = 106,9375

Y para terminar por hoy (el convertidor decimal a hexadecimal otro día :p) dejo ambos códigos para análisis, recuerdo que pueden encontrarlos también en Bl4ck-P0rtal.org


Multiplicación.bat
@echo off
:: call :decimal_multi numero_decimal numero_entero
:: devuelve %multi%

:decimal_multi
setlocal
set num1=%1
set num2=%2

for /f "tokens=1,2 delims=." %%a in ("%num1%") do (
call :len %%b
set /a part1=%%a*%num2%
set /a part2=%%b*%num2%
)

call set p2=%%part2:~-%long%%%
set minus=%long%
call :len %part2%
set /a minus=%long%-%minus%
call set p1=%%part2:~0,%minus%%%

set /a suma=%p1%+%part1%
endlocal && set multi=%suma%.%p2% && goto :eof

:len
set len=%1
set long=0
:_loop
call set var=%%len:~%long%,1%%
if not defined var (goto :eof)
set /a long+=1
goto _loop


División.bat

@echo off
:: call :decimal_division dividendo divisor
:: devuelve: %division%

:decimal_division
setlocal
set dividendo=%1
set divisor=%2
set decimales=0

set /a "entero=%dividendo%/%divisor%"
set /a "resto0=%dividendo%%%%divisor%"

:div_decimal
if [!resto%decimales%!]==[0] goto div_fin
set /a sig=%decimales%+1
set /a decimal%decimales%=!resto%decimales%!0/%divisor%
set /a resto%sig%=!resto%decimales%!0%%%divisor%
set /a "decimales+=1"
goto div_decimal

:div_fin
for /l %%a in (0,1,%decimales%) do (set final=!final!!decimal%%a!)
endlocal && set division=%entero%.%final% && goto:eof

1 Response
  1. Anónimo Says:

    Tengo una duda la cual llevo ya mucho tiempo dandole vueltas. Imaginemos que tenemos una cifra (por ejemplo: 0,2210281825). Si quisieramos hallar con que división de números enteros obtendría esa cifra (esta cifra la introduciría el usuario). ¿COmo podría hacerse? Había pensado probando con contadores pero la verdad es que no tengo muy claro si se podría hacer un programa así en BATCH. ¿Me puedes ayudar? Mario