apop85
Goto Top

Berechnen auf nahezu beliebige Kommastellen nur mit Batch (30000 Stellen getestet)

Hey zusammen. Hab da mich bezügl. diesem Thema auch umgeschaut hier. Die meisten benutzten zur Lösung ein VB-Script o.ä.
Habe hier mal was zurechtgebastelt anhand dem was ich in der Grundschule gelernt habe... von Kopf dividieren. Eine stelle nach der anderen...

Damits auch lustig wird habe ich mal ein Batch geschrieben der eine gerundete Zahl von PI auf undefinierte länge in ein txt ausspuckt. Ganz nach der Grundschulmethode berechnet.

Hab schon viel gelesen über das Thema und meist hiess es einfach es gehe nicht(Unpassendes Werkzeug für Aufgabe). Natürlich sind auch die netten VBS-4-Zeiler ganz nett und auch effizienter, ich dachte mir jedoch, dass es irgendwie auch so gehen sollte.
Und Voila:

@echo off & setlocal
set vorkomma1=49932 & set vorkomma2=15893
set nachkomma1=159 & set nachkomma2=900
set /a vorkomma1=%vorkomma1%*1000
set /a vorkomma2=%vorkomma2%*1000
set /a nenner=%vorkomma1%+%nachkomma1%
set /a teiler=%vorkomma2%+%nachkomma2%
set timer=0
set div1=0
echo Auf wieviele Stellen soll gerechnet werden?
set /p stellen=
set /a stellen=%stellen%+1
:HOME
set /a timer=%timer%+1
echo Berechnung Kommastelle:%timer%
if %timer% == %stellen% goto DONE
set /a div0=%nenner%/%teiler%
if %div0% == 0 ( 
	set "zahl=0" & set "div1=0"  
	) else ( 
	set zahl=%div0% & set /a div1=%div0%*%teiler%
)

if %div1% GEQ 1 ( set /a nenner=%nenner%-%div1% )
set /a nenner=%nenner%*10

if %timer% LEQ 1 set "zahl=%zahl%."  
<nul set/p"%zahl%" >>Ausgabe.txt  
goto HOME

:DONE
set /a stellen=%stellen%-1
echo Die Division wurde auf %stellen% Nachkommastellen berechnet.
ping -n 10 localhost >NUL
exit
Erklärung:

Er überprüft ob die Zahl A (%nenner%) geteilt durch B (%teiler%) 0 ergibt (Zeile 18) und wenn dies so ist setzt er die Variable C (%zahl%) welche in das Resultat einfliesst auf 0 (Zeile 19) und Spring zum Schluss wo er die Ursprüngliche Variable A, sollte C = 0 sein, multipliziert mit 10. Danach wird das ganze wiederholt bis die gewünschte Kommastelle erreicht ist.

Sollte nun aber die Division von A durch B nicht 0 sein so setzt er die Variable C als Resultatschnippsel (%zahl%) danach multipliziert das Script die Variable C mit der Variable B (Zeile 21) und zieht dieses Resultat wieder der Variable A ab (Zeile 24). (Komplizierte schreibweise für die Division auf dem Blatt)
http://de.wikipedia.org/wiki/Schriftliche_Division

Ich versuch das mal bildlich darzustellen. Dividieren von Hand im zusammenhang mit diesem Beitrag:
-- Also Man nehme wie z.B. in diesem Beispiel eine dreistellige Zahl --
Zu Teilende Zahl = 49932.195 / Teiler = 123.456
-- Diese wird anhand des Punktes in zwei Variablen aufgeteilt --
   a = 49932
   b = 195
-- Dann wird a x 1000 gerechnet, sozusagen um die Kommastellen weg zu multiplizieren --
   a x 1000 = 49932000
   c = a + b
-- c ist nun die Gesammte zu Dividierende Zahl. Das selbe Schema widerholen wir auch beim Dividend (d), also der Zahl durch die c geteilt werden soll --
c : d =
49932195 : 123456    = 404 - Rest 55776  <-- 1. Variabel = 404
   557760 : 123456   = 4   - Rest 63936  <-- 2. Variabel = 4
    639360 : 123456  = 5   - Rest 22080  <-- 3. Variabel = 5
     220800 : 123456 = 1   - Rest 97344  <-- 4. Variabel = 1
usw...
-- Jetzt hat man schon auf 3 Kommastellen berechnet --
Die Ausgabe kann in eine Datei geschehen so wie in meinem Beispiel oben oder aber man macht folgendes:
if defined Resultat ( 
    set "Resultat=%Resultat%%Zahl%"   
    ) else (
    set "Resultat=%Zahl%"  
)
echo %Resultat%  

Warum Multipliziere ich die Zahlen am Anfang mit 1000?
Dies mache ich weil Dos ja bekanntlich keine Kommastellen von alleine rechnen kann. Also wenn ich z.B. 1.123 habe steht 1 für %vorkomma1% und und 123 für %nachkomma1%. Durch die Multiplikation kann ich nun die beiden zusammenrechnen zu 1123 perfekt also für die Division (Da Dos ja nur ganze Zahlen schluckt)
Möchte man jetzt mehr Nachkommastellen so muss man pro Kommastelle die Multiplikation um 10 erhöhen. Aber achtung Dos bringts nur bis Summen von +/- 200'000'000 höher rechnet es nicht. Daher habe ich auch eine Schleife gemacht wo die Kommastellen im 6er-Pack berechnet werden.
set /a vorkomma1=%vorkomma1%*1000
set /a vorkomma1=%nachkomma1%+%vorkomma1%

Was man bei einer Umsetzung zu einem Taschenrechner beachten muss, ist dass nicht alle immer 1.100 eingeben um mit 1.1 zu rechnen. Ausserdem kann er dann 1.1 und 1.001 nicht unterscheiden beides ergibt bei seiner Rechnung 1001 ((vorkomma x 1000)+nachkomma)

Ich hab dies folgendermassen gelöst:
for /f "delims=. tokens=1-2" %%a in ("%nenner%") do (  
				Set "=vorkomma1%%a"  
				Set "^nachkomma1=%%b"  
)


for /f "delims=. tokens=1-2" %%a in ("%teiler%") do (  
				Set "vorkomma2=%%a"  
				Set "nachkomma2=%%b"  
)

Somit teilt er schon mal auf in Vor- und Nachkommastelle des Nenners und dem Teiler.

nun überprüft man die Eingabe
if "%nachkomma1:~1,1%" == "" set "nachkomma1=%nachkomma1%0"  
if "%nachkomma2:~1,1%" == "" set "nachkomma2=%nachkomma2%0"  
if "%nachkomma1:~2,1%" == "" set "nachkomma1=%nachkomma1%0"  
if "%nachkomma2:~2,1%" == "" set "nachkomma2=%nachkomma2%0"  
So ergänzt er die Eingabe 1.1 auf 1.100. Somit rechnet er wieder mit 1100 und nicht mit 1001.
Dies kann mann auch als rechenvorlage benutzen für einen kleinen Rechner.

Lg.

Apop

Auf Wunsch noch der "VBS-4-Zeiler" den ich gefunden hab. made by @bastla
gefunden auf Batch - Dividieren ? (mit kommastelle)
@echo off & setlocal
set Zahl1=120
set Zahl2=13
set Stellen=2

set R=%temp%\Rechne.vbs
echo Set a=WScript.Arguments:WScript.Echo FormatNumber(Eval(a(0)),a(1))>%R%
for /f %%i in ('cscript //nologo %R% "%Zahl1%/%Zahl2%" %Stellen%') do set Ergebnis=%%i  
echo %Ergebnis%

Content-ID: 204906

Url: https://administrator.de/contentid/204906

Ausgedruckt am: 26.11.2024 um 11:11 Uhr

106543
106543 12.04.2013 um 13:56:04 Uhr
Goto Top
Hi,

nett face-smile wärst du so lieb und würdest mir auch mal so einen VBS 3-Zeiler posten ?

Grüße
Exze
Apop85
Apop85 12.04.2013 aktualisiert um 17:19:25 Uhr
Goto Top
Hey.

Ich editier ihn noch rein wenn ich ihn wieder finde... Hab in letzter Zeit viel Recherchiert und weiss auch nicht mehr genau was ich wo gefunden habe face-smile

(p.s. 4 Zeilen sind nur ne schätzung... Jedenfalls massiv weniger als 193 Zeilen face-smile, die Erinnerungen an den Eintrag sind Verschleiert face-smile)

Weiss zufällig jemand eine Lösung wie ich das mit der Ausgabe in eine Einzige zeile fertigkriege?


Gruss
Apop

<edit>
VBScript wurde zum Haubtbeitrag hinzugefügt
</edit>
Endoro
Endoro 12.04.2013 um 18:56:38 Uhr
Goto Top
Hallo Apop85,

Zitat von @Apop85:
Weiss zufällig jemand eine Lösung wie ich das mit der Ausgabe in eine Einzige zeile fertigkriege?

geht so:
<nul set/p"=XXX "  

Leerzeichen zwischen "=" und dem ersten Buchstaben werden nur in XP dargestellt, nicht in Vista oder später. Die Leerzeichen also an den Text anhängen, wie das in meinem Beispiel.

Gruss!
Apop85
Apop85 12.04.2013 um 23:52:46 Uhr
Goto Top
Sorry versteh nicht ganz was das macht.
In welchem Kontext kommt das? Hab schon versucht rubzubasteln indem ich NUL durch Dateinamen austausche oder xxx als %zahl% nehm

geht so:
<nul set/p"=XXX "  

Leerzeichen zwischen "=" und dem ersten Buchstaben werden nur in XP dargestellt, nicht in Vista oder später. Die

evtl. könntest du mir das etwas näher erläutern.

Danke & Gruss
rubberman
rubberman 13.04.2013 aktualisiert um 15:21:11 Uhr
Goto Top
Hallo Apop85,

wenn du bei SET /P Whitespaces (Leerzeichen oder Tabs) am Zeilenanfang stehen hast, dann werden die auf neueren Windowsversionen verschluckt.

Workaround:
@echo off &setlocal

:: Backspace erzeugen
for /f %%a in ('"prompt $H &for %%b in (1) do rem"') do set "bs=%%a"  

<nul set /p "=   123 "  
echo funktioniert nur fuer XP und aelter.
<nul set /p "=.%bs%   123 "  
echo funktioniert auch unter Vista und neuer.
pause
Das Backspace Zeichen funktioniert also genauso als würdest du die Backspace Taste drücken. Für die Ausgabe in einem Batchfenster ist das absolut OK. Bei der Umleitung in eine Datei würde aber auch der Punkt und das Backspace Zeichen mit in der Datei landen.

Grüße
rubberman
Apop85
Apop85 16.04.2013 um 13:13:28 Uhr
Goto Top
wenn du bei SET /P Whitespaces (Leerzeichen oder Tabs) am Zeilenanfang stehen hast, dann werden die auf neueren Windowsversionen
verschluckt.
Good to know. Ich überprüf dies einfach mittels %variable:~2,1%
also

if "%variable:~2,1%" == "" set "variable=%variable%0"  
selbiges mit zweiter Kommastelle und ganz am Anfang überprüf ich ob nach dem Komma überhaubt was geschrieben ist. Falls nicht dann set variable=000

Bei der Umleitung in eine Datei würde aber auch der Punkt und das Backspace Zeichen mit in der Datei landen.
Kann man ja auch mit obiger Variante wegrationalisieren ;)