Convert decimal to base N and vice versa

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
miskox
Posts: 668
Joined: 28 Jun 2010 03:46

Convert decimal to base N and vice versa

#1 Post by miskox » 03 Jun 2014 03:15

Based on this Aacini's work viewtopic.php?f=3&t=5665 here is the converter for converting between decimal numbers and base-N (and vice versa). It even calculates the length (number of characters) of the result.

Base-N can be between 2 and 36 (inclusive).

Saso

Code: Select all

@echo off
setlocal

set "map=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

rem Separate digits in map into array elements
set i=0
for /F "delims=" %%a in ('cmd /U /C echo %map%^| find /V ""') do (
   set /A map[%%a]=i, i+=1
)

echo Enter decimal numbers, zero to end
:loop
   echo/
   set basen=0
   set /p "basen=Base: "

   if %basen% LSS 2 goto :loop
   if %basen% GTR 36 goto :loop


   set /P "decimal=Enter number:    "
   set /a decimalorg=decimal

set /a num_digits=-1
:0
set /A digit=decimal%%%basen%
set /a decimal/=%basen%
set /a num_digits+=1
if "%digit%"=="0" if "%decimal%"=="0" echo num_digits:%num_digits%&&goto :1
goto :0

:1
   set /a num_digits2=num_digits-1
   set /a decimal=decimalorg
   set "baseout="
   for /L %%N in (1,1,%num_digits%) do call :work1
   echo In base %basen%: %baseout%

   set decimal=0
   for /L %%N in (0,1,%num_digits2%) do call :work2 %%N
   echo Back in base 10: %decimal%

if %decimal% neq 0 goto loop
goto :EOF

:work1
set /A digit=decimal%%%basen%
set /a decimal/=%basen%
call set baseout=%%map:~%digit%,1%%%baseout%
exit /B

:work2
call set index=%%baseout:~%1,1%%
set /A decimal=decimal*basen+map[%index%]
exit /B

miskox
Posts: 668
Joined: 28 Jun 2010 03:46

Re: Convert decimal to base N and vice versa

#2 Post by miskox » 05 Jun 2014 02:02

Here is an update. I added small letters a-z to the list of available characters. Now the maximum base is 62.

Because dos does not distinguish between capital and small letters in variable names:

Code: Select all

set mapA=10


and

Code: Select all

set mapa=40


mapping small letters to array does not work. Instead I used a temporary file.

Code: Select all

@echo off
setlocal

set "map=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

set random_file=%random%_file.tmp
set i=0
for /F "delims=" %%a in ('cmd /U /C echo %map%^| find /V ""') do call :makefile %%a

echo Enter decimal numbers, zero to end
:loop
   echo/
   set basen=0
   set /p "basen=Base: "

   if %basen% LSS 2  goto :loop
   if %basen% GTR 62 goto :loop

   set /P "decimal=Enter number:    "
   set /a decimalorg=decimal

set /a num_digits=-1
:0
set /A digit=decimal%%%basen%
set /a decimal/=%basen%
set /a num_digits+=1
if "%digit%"=="0" if "%decimal%"=="0" echo num_digits:%num_digits%&&goto :1
goto :0

:1
   set /a num_digits2=num_digits-1
   set /a decimal=decimalorg
   set "baseout="
   for /L %%N in (1,1,%num_digits%) do call :work1
   echo In base %basen%: %baseout%

   set decimal=0
   for /L %%N in (0,1,%num_digits2%) do call :work2 %%N
   echo Back in base 10: %decimal%

if %decimal% neq 0 goto loop
if exist %random_file%.tmp2 del %random_file%.tmp2
if exist %random_file%      del %random_file%
goto :EOF

:work1
set /A digit=decimal%%%basen%
set /a decimal/=%basen%
>%random_file%.tmp2 (findstr /B /C:"#%digit%#" %random_file%)

for /f "tokens=2 delims=#" %%q in (%random_file%.tmp2) do set new_digit=%%q
set baseout=%new_digit%%baseout%
exit /B

:work2
call set index=%%baseout:~%1,1%%

>%random_file%.tmp2 (findstr /E /C:"#%index%#" %random_file%)

for /f "tokens=1 delims=#" %%q in (%random_file%.tmp2) do set /a new_digit=%%q

set /A decimal=decimal*basen+new_digit
exit /B

:makefile
>>%random_file% (echo #%i%#%1#)
set /a i+=1
goto :EOF


Saso

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Convert decimal to base N and vice versa

#3 Post by penpen » 05 Jun 2014 03:33

Although it is unusual, you may increase the number of supported number systems, by using (for example):
- multiple characters per digit (decimal numbers),
- a digit separator (_),
- a number encloser (left side "{ "; right side " }"),
- a number-base separator (#), and
- the base specifier (decimal number).

So you could represent the number 16 (decimal) as:
{16}_17 = {1;0}_16 = {1;6}_10 = {3;1}_5 = {1;0;0}_4 = {1;0;0;0}_2.

In theory you could represent any number in any number system;
but if you want to calculate with this numbers, then it should start getting problematic when reaching base 43640 ([sqrt(0x7FFFFFFF)]-1) in batch.

penpen

AndrewH7
Posts: 1
Joined: 25 Nov 2014 08:17

Re: Convert decimal to base N and vice versa

#4 Post by AndrewH7 » 25 Nov 2014 08:36

DBUG can convert to base 2 & 16, & be run from batch file.

Post Reply