Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
miskox
- Posts: 668
- Joined: 28 Jun 2010 03:46
#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
#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:
and
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
#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
#4
Post
by AndrewH7 » 25 Nov 2014 08:36
DBUG can convert to base 2 & 16, & be run from batch file.