Binärzahlen Umrechner mit Batch programmieren?
Funktioniert das? Der Rechner muss vom Zehnersystem ins Dualsystem umrechnen. Vielleicht könnte einer von euch mir dabei helfen oder ein ihr habt ihr irgendwelche Ideen?
Danke schon mal für eure Antworten.
4 Antworten
Mit Batch kenne ich mich nicht so gut aus.
Ich kann dir aber den Algorithmus erklären. Nennen wir die Dezimalzahl : = x
- Du teilst x durch 2
- Das Ergebnis wird dein neues x
- Den Rest schreibst du an den Anfang deiner Ergebniszeichenkette
- Weiter mit 1
Das Ganze machst du solange , bis x=0 ist.
So weit ich weiß ist %% der Modulo-Operator.
Wie man Batch-Schleifen programmiert weiß ich nicht.
Stimmt, ich bin von positiven Zahlen ausgegangen. fragfelix12 hat darüber nichts geschrieben. Dafür eignet sich mein Algorithmus auch für Systeme die keine Zweierpotenzen sind.
erstmal auf die "harte" Tour. Batch pur:
@echo off
setlocal EnableDelayedExpansion
chcp 65001 >nul & rem Umlaute richtig darstellen.
:start
set /p "__Input= Bitte eine Zahl eingeben eingeben : "
rem prüfen ob eine gültige Zahl eingegeben wurde
set /a "__dummy=__Input+0" 2>nul
if "%__dummy%" neq "%__Input%" (
echo "%__Input%" ist keine zulässige Zahl ^( -2147483648..2147483647^)
set "__Input="
goto :Start
)
rem die Problematik bei negativen Integern ist diese binär "richtig" darzustellen...
rem der "Teileralgoritmus" funktioniert nur mit positiven Zahlen! (-5 würde -10-1 ausspucken...:p)
rem um für die Brechnung die Zahl positiv zu halten addiere ich die negative Zahl (Subtraktion) zum/vom max Integer (Positiv) binär 01111111111111111111111111111111= 2.147.483.647 und korrigiert um plus 1
rem (wer jetzt häääää???? denkt,warum nicht einfach das Vorzeichen löschen? hat Binärmathematik noch nicht begriffen....)
rem egal ,damit sind wir das Vorzeichenbit los )
rem klingt wie Irrsinn, aber Batch "vertägt" keine Zahlen kleiner -2147483648 größer 2147483647 also muss man etwas zaubern...
if %__Input% geq 0 (
set "__Number=%__Input%"
) else (
rem ...das Mathematik ist ja so toll aber beim programmieren mit 32BitInteger wäre 2147483648 + __Input ein Fehler!!!!
rem darum erst nach der Subtraktion 1 addieren!
set /a "__Number=2147483647 + __Input + 1"
)
set "__Binary="
:Dec2Bin
rem Modulooperation der eingegebenen Zahl mit 2 ergibt einen rest 0 oder 1, anschließend die eingegebene Zahl durch zwei Teilen (für einen eventuellen nächsten Durchlauf)
rem set /a kann mehrere Operationen in einem Aufruf ausführen... (schneller)
set /a "Digit=__Number %% 2,__Number /= 2"
rem schreibe das neue Digit vor das vorherige...
set __Binary=%Digit%%__Binary%
rem solange die Schleife ausführen, bis nur noch 0 beim Teilen übrig ist.
if %__Number% neq 0 goto :Dec2Bin
rem wenn %__Input% kleiner 0 war...
if %__Input% lss 0 (
rem ...mindestens 30 Nullen voranstellen
set "__Binary=0000000000000000000000000000000%__Binary%"
rem ...nur die letzten 31 Zeichen verwenden und eine 1 voranstellen (damit sind es 32 bit)
set "__Binary=1!__Binary:~-31!"
)
echo Decimal: %__Input% = Binary: %__Binary%
echo Wieder zurückkonvertieren:
Rem und das Ganze wieder zurück nach Dezimal
set "__dummyBin=%__Binary%"
set "__Decimal="
for /L %%i in (1,1,32) do (
if defined __dummyBin (
set /a "__Decimal=(__Decimal<<1)|!__dummyBin:~0,1!"
set "__dummyBin=!__dummyBin:~1!"
)
)
echo %__Decimal%
goto start
...Wenn Dir jetzt die Haare zu Berge stehen und das Hirn ausbrennt... , dann kann ich Dir Trost spenden...
...es geht auch anders...
Mit Batch hat man auch die Möglichkeit andere Progamme die Arbeit erledigen zu lassen. ...und Powershell ist auch auf jedem Windows "eingebaut" und erlaubt den direkten Aufruf von Befehlen/Cmdlets über seine Kommandozeile.
...Also einfach munter https://docs.microsoft.com/de-de/dotnet/api/system.convert.tostring?view=netframework-4.8#System_Convert_ToString_System_Int16_System_Int32_
die Arbeit machen lassen:
@echo off
chcp 65001 >nul
:start
set /p "__Input= Bitte eine Zahl eingeben eingeben : "
set /a "__dummy=__Input+0" 2>nul
if "%__dummy%" neq "%__Input%" (
echo "%__Input%" ist keine zulässige Zahl ^( -2147483648..2147483647^)
set "__Input="
goto :Start
)
rem Powershell -c "&{[convert]::ToString(%__Input%,2)}" der variable %__Binary% zuweisen...
for /f %%a in ('Powershell -c "&{[convert]::ToString(%__Input%,2)}"') do (
set "__Binary=%%a"
)
echo Decimal: %__Input% = Binary: %__Binary%
echo Wieder zurückkonvertieren:
for /f "usebackq" %%a in (`Powershell -c "&{[convert]::ToInt32('%__Binary%',2)}"`) do (
set "__Decimal=%%a"
)
echo %__Decimal%
goto start
Wenn es so einfach geht, warum dann das Monster?....
Weil ich's kann? und es gibt durchaus Situationen wo man wissen sollte wie es auch ohne vorgefertigte Funktionen klappt.
Mit der ersten Variante kannst Du auf jeden Fall ein gewisses Renommee ernten...
2.Anlauf:
...noch mal Pure Batch:
...auch ohne Powershell ,in pure Batch get es immer noch etwas eleganter...
... es wird per logischem AND 1 das niedrigste Bit abgefragt und die Eingangszahl um 1 Bit nach rechts geschoben (entspricht n/2 ist aber schneller). Nach höchstens 32 Schleifendurchläufen hat man alle nötigen Bits. Es geht also ganz ohne die Frickelei mit Modulo und Division... und damit auch ohne die Stringoperationen...
@echo off
setlocal EnableDelayedExpansion
chcp 65001 >nul & rem Umlaute richtig darstellen.
:start
set /p "__Input= Bitte eine Zahl eingeben eingeben : "
rem prüfen ob eine gültige Zahl eingegeben wurde
set /a "__dummy=__Input+0" 2>nul
if "%__dummy%" neq "%__Input%" (
echo "%__Input%" ist keine zulässige Zahl ^( -2147483648..2147483647^)
set "__Input="
goto :Start
)
set "__Number=%__Input%"
set "__Binary="
for /l %%a in (1,1,32) do (
rem zum debugen: echo !__Number!
rem Digit n AND 1 , 1Bit Nach rechts schieben
set /a "Digit=__Number & 1 ,__Number>>=1"
set "__Binary=!Digit!!__Binary!"
if !__Number! equ 0 goto :break
)
:break
echo Decimal: %__Input% = Binary: %__Binary%
echo Wieder zurückkonvertieren:
set "__dummyBin=%__Binary%"
set "__Decimal="
for /L %%i in (1,1,32) do (
if defined __dummyBin (
set /a "__Decimal=(__Decimal<<1)|!__dummyBin:~0,1!"
set "__dummyBin=!__dummyBin:~1!"
)
)
echo %__Decimal%
goto start
pause
...manche Idee braucht eben etwas mehr Zeit um zu wachsen...🤓😏
..gefällt mir rein technisch sogar besser als die Powershellvariante
Hier wäre mein Vorschlag:
@echo off
:main
set "result="
set /p "num_0=Dezimalzahl: >"
call :deleteLeadingZero %num_0%
set /a num_0 = %errorlevel%
set /a number = %num_0%
:do_while
set /a number = %number% / 2
set /a binary = %number% %% 2
set "result=%binary%%result%"
if %number% NEQ 0 goto do_while
echo %num_0% in binaer: %result% &echo+
goto main
:deleteLeadingZero
exit /B %~1
Hier ist der Link zu dem Skript auf GitHub: https://github.com/timlg07/Batch_Tools/blob/master/1-1-int2binary.bat
Habe zu jedem Skript eine Erklärung, auch wenn die Bedienung dieses Skriptes recht trivial ist: https://github.com/timlg07/Batch_Tools/blob/master/1-1-int2binary.txt
Wenn die Batch Teil eines größeren Programmes sein soll und Zahlen jeder Art konvertieren soll, musst du negative Zahlen im Voraus abfangen und eigens behandeln.
Das funktioniert nur mit positiven Zahlen! 😤