Mathe-Parser

Übersicht BlitzBasic Codearchiv

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

Froggy

Betreff: Mathe-Parser

BeitragSa, Jan 27, 2007 13:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,

ich habe einen String-Ausrechner programmiert, der kann:

- Konstanten durch ihre Werte ersetzen (pi->3.14159)
- Hoch-vor-Punkt-vor-Strich-Regeln Wink
- Klammern ausrechnen
- Funktionen mit einer oder zwei Variablen benutzen
(wären theoretisch auch mehr möglich)

- Negativ: Teils starke Rundungsfehler

Der Code:
Code: [AUSKLAPPEN]

;Stringrechner
Function calc#(r$) ;calc(Rechnungsstring)

;Umformungen + Konstanten
r=Lower(r)
r=Replace(r,"'","^")
r=Replace(r," ","")
r=Replace(r,"pi",3.141592653589)
r=Replace(r,"e",2.718281828459)

;Klammern
While Instr(r,"(") > 0

kla=1
While Mid(r,kla,1)<>"(" Or (Instr(Mid(r,kla+1),"(") < Instr(Mid(r,kla+1),")") And Instr(Mid(r,kla+1),"(") > 0)
kla=kla+1
Wend

klz=Instr(Mid(r,kla+1),")")+kla

If kla = 1 Then
r=calc2(Mid(r,kla+1,klz-1-kla))+Mid(r,klz+1)
ElseIf (Mid(r,kla-1,1)="+" Or Mid(r,kla-1,1)="-" Or Mid(r,kla-1,1)="*" Or Mid(r,kla-1,1)="/" Or Mid(r,kla-1,1)="^" Or Mid(r,kla-1,1)="(") Then
r=Left(r,kla-1)+calc2(Mid(r,kla+1,klz-1-kla))+Mid(r,klz+1)
Else

fna = kla-1
While Mid(r,fna,1) <> "+" And Mid(r,fna,1) <> "-" And Mid(r,fna,1) <> "*" And Mid(r,fna,1) <> "/" And Mid(r,fna,1) <> "^" And Mid(r,fna,1) <> "(" And Mid(r,fna,1) <> ","
fna = fna-1
If fna = 0 Then Exit
Wend

;Funktionen
If Instr(Mid(r,fna+1,klz-1-fna),",")=0 Then
z1#=calc2(Mid(r,kla+1,klz-1-kla))
Else
z1#=calc2(Mid(r,kla+1,Instr(r,",")-1-kla))
z2#=calc2(Mid(r,Instr(r,",")+1,klz-1-Instr(r,",")))
EndIf

Select Mid(r,fna+1,kla-1-fna)

;1-Variablen-Funktionen
Case "sin" r=Left(r,fna)+Sin(z1)+Mid(r,klz+1)
Case "cos" r=Left(r,fna)+Cos(z1)+Mid(r,klz+1)
Case "tan" r=Left(r,fna)+Tan(z1)+Mid(r,klz+1)
Case "asin" r=Left(r,fna)+ASin(z1)+Mid(r,klz+1)
Case "acos" r=Left(r,fna)+ACos(z1)+Mid(r,klz+1)
Case "atan" r=Left(r,fna)+ATan(z1)+Mid(r,klz+1)
Case "sqr" r=Left(r,fna)+Sqr(z1)+Mid(r,klz+1)
Case "floor" r=Left(r,fna)+Floor(z1)+Mid(r,klz+1)
Case "ceil" r=Left(r,fna)+Ceil(z1)+Mid(r,klz+1)
Case "ln" r=Left(r,fna)+Str(Log(z1))+Mid(r,klz+1)
Case "lg" r=Left(r,fna)+Log(z1)/Log(10)+Mid(r,klz+1)
Case "int" r=Left(r,fna)+Str(Int(z1)+(Float(z1) Mod 1 = 0.5))+Mid(r,klz+1)

;2-Variablen-Funktionen
Case "mod" r=Left(r,fna)+Str(Float(z1) Mod Float(z2))+Mid(r,klz+1)
Case "log" r=Left(r,fna)+Log(z1)/Log(z2)+Mid(r,klz+1)
Case "max" r=Left(r,fna)+Str((z1>=z2)*z1+(z2>z1)*z2)+Mid(r,klz+1)
Case "min" r=Left(r,fna)+Str((z1<=z2)*z1+(z2<z1)*z2)+Mid(r,klz+1)
Case "root" r=Left(r,fna)+Str(z1^(1/z2))+Mid(r,klz+1)

End Select

EndIf
Wend

;Restliche Berechnung
r=calc2(r$)

;Ausgabe
Return Float(r)

End Function


;2. Funktion
Function calc2$(r$)

;Voreinstellungen
Repeat
r=Replace(r,"++","+")
r=Replace(r,"+++","+")
r=Replace(r,"+-","-")
r=Replace(r,"-+","-")
r=Replace(r,"--","+")
r=Replace(r,"---","-")
Until Instr(r,"++")=0 And Instr(r,"--")=0 And Instr(r,"+-")=0 And Instr(r,"-+")=0
If Left(r,1)="+" Then r=Mid(r,2)

;verschiedene Operatoren

;^
While Instr(r,"^")
r=calc3(r,"^")
Wend

;*/
While Instr(r,"*") > 0 Or Instr(r,"/") > 0

While Instr(r,"*-")>0
r$=Left(r,Instr(r,"*-"))+"~"+Mid(r,Instr(r,"*-")+2)
Wend

While Instr(r,"/-")>0
r$=Left(r,Instr(r,"/-"))+"~"+Mid(r,Instr(r,"/-")+2)
Wend

z$="*"
If (Instr(r,"/") < Instr(r,"*") And Instr(r,"/")>0) Or Instr(r,"*") = 0 Then z="/"
r=calc3(r,z)
Wend

;+-
While Instr(r,"+") > 0 Or Instr(Mid(r,2),"-") > 0
If Left(r,1) = "-" Then r="~"+Mid(r,2)

z="+"
If (Instr(r,"-") < Instr(r,"+") And Instr(r,"-")>0) Or Instr(r,"+") = 0 Then z="-"
r=calc3(r,z)
Wend

;Ausgabe
Return r$

End Function


;3.Funktion
Function calc3$(r$,z$)

;Zahlbegrenzungen
op=Instr(r,z)

za=op-1

While Mid(r,za,1) <> "+" And Mid(r,za,1) <> "-" And Mid(r,za,1) <> "*" And Mid(r,za,1) <> "/" And Mid(r,za,1) <> "^"
za=za-1
If za = 0 Then Exit
Wend

ze=op+1
While Mid(r,ze,1) <> "+" And Mid(r,ze,1) <> "-" And Mid(r,ze,1) <> "*" And Mid(r,ze,1) <> "/" And Mid(r,ze,1) <> "^" And ze<=Len(r)
ze=ze+1
Wend

;Minusrückänderung
r=Replace(r,"~","-")

;Verschiedene Operationen
Select z
Case "-" r=Left(r,za)+Str(Float(Mid(r,za+1,op-1))-Float(Mid(r,op+1,ze-1)))+Mid(r,ze)
Case "+" r=Left(r,za)+Str(Float(Mid(r,za+1,op-1))+Float(Mid(r,op+1,ze-1)))+Mid(r,ze)
Case "/" r=Left(r,za)+Str(Float(Mid(r,za+1,op-1))/Float(Mid(r,op+1,ze-1)))+Mid(r,ze)
Case "*" r=Left(r,za)+Str(Float(Mid(r,za+1,op-1))*Float(Mid(r,op+1,ze-1)))+Mid(r,ze)
Case "^" r=Left(r,za)+Str(Float(Mid(r,za+1,op-1))^Float(Mid(r,op+1,ze-1)))+Mid(r,ze)
End Select

Return r$

End Function
;/Stringrechner



Bitte versucht so viele verschiedene Rechnungen, wie ihr kennt, und meldet mir alle Fehler!
(Aber nur die vorhandenen Konstanten und Funktionen nutzen Wink )



Danke,
Froggy




edit by Triton---
Titel geändert.
  • Zuletzt bearbeitet von Froggy am So, Jan 28, 2007 13:09, insgesamt 3-mal bearbeitet
 

Krümel

BeitragSa, Jan 27, 2007 14:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Evtl. solltest du Leerzeichen im Text replacen, denn:
Print calc("1 + (1+1)")
führt zum einfrieren.
 

Froggy

BeitragSa, Jan 27, 2007 22:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, danke.

Habs hinzugefügt.

Edit: Hab grad einen schwerwiegenden Fehler korrigiert.
60-1+1 gab 58, weil es zuerst 1+1 und dann 60-2 gerechnet hat.

Ich hoffe, dass es keine solche Fehler mehr gibt.

Smily

BeitragSo, Jan 28, 2007 15:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Nach sowas habe ich gerade gesucht Shocked
Kannst du Gedanken lesen? Laughing

thx,
Smily0412
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org
 

Krümel

BeitragSo, Jan 28, 2007 19:12
Antworten mit Zitat
Benutzer-Profile anzeigen
ich finde deinen code sehr interessant , deshalb habe ich mir mal gedanken gemacht, wie ich das gemacht hätte.
Meine Idee: ich lasse einfach BlitzBasic die Berechnung durchführen.
Und das geht so:
Code: [AUSKLAPPEN]

Rechnung$="2^3*17.245*log(13)-(17.9+22.11)"

f=WriteFile("c:\tmpFile01")
s$="f=WriteFile("+Chr$(34)+"c:\tmpfile02"+Chr$(34)+")"+Chr$(10)
s$=s$+"Writefloat f,("+Rechnung+")"+Chr$(10)+"CloseFile(f)"+Chr$(10)
WriteLine f,s:CloseFile f : Delay 2000
ExecFile SystemProperty("appdir")+"\blitzcc.exe +q c:\tmpFile01" : Delay 2000
f=ReadFile("c:\tmpfile02") : Loesung#=ReadFloat(f) : CloseFile f
DeleteFile "c:\tmpfile01" : DeleteFile "c:\tmpfile02"

Print Loesung
WaitKey()

Das funktioniert logischerweise nur wenn BlitzBasic istalliert ist.
D.h. würde man dieses programm als exe compiliert auf einem "nicht BlitzBasic" - Rechner laufen lassen gehts natürlich nicht.
  • Zuletzt bearbeitet von Krümel am So, Jan 28, 2007 21:18, insgesamt 2-mal bearbeitet
 

Froggy

BeitragSo, Jan 28, 2007 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Woah, krasser Code!
Ich check irgendwie garnichts von dem, was du da gemacht hast.

Dass mein Code nicht perfekt ist, ist klar.
Da könnte man bestimmt noch soviel verbessern, dass er nur noch halb so lang ist.
 

FWeinb

ehemals "ich"

BeitragSo, Jan 28, 2007 20:39
Antworten mit Zitat
Benutzer-Profile anzeigen
könte man nicht auch den taschenrechner von Widows nehmen (kann leider die parameter nicht aber müste das nicht gehen
"Wenn die Menschen nur über das sprächen, was sie begreifen, dann würde es sehr still auf der Welt sein." Albert Einstein (1879-1955)
"If you live each day as if it was your last, someday you'll most certainly be right." Steve Jobs
 

Froggy

BeitragSo, Jan 28, 2007 20:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie meinst du das? Der Rechner sollte ja in BB nutzbar sein (z.B. für ein Funktionsgrapher-Programm).

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Jan 28, 2007 20:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Sinn eines Stringrechners ist, dass man 'beliebig' lange Rechenaufgaben stellen kann. Die calc.exe von Windows kann 'nur' 32 Stellen berechnen. Im zuge dessen, währe es auch sinnvoll zB die pi-Variable um ein paar Stellen zu erhöhen. Habe grad so eine pi.txt bei mir gefunden mit 88k Stellen.

edit1: Sorry, bin eben von was anderem ausgegangen. Embarassed Beitrag nicht beachten...
  • Zuletzt bearbeitet von hectic am So, Jan 28, 2007 20:49, insgesamt einmal bearbeitet
 

FWeinb

ehemals "ich"

BeitragSo, Jan 28, 2007 20:49
Antworten mit Zitat
Benutzer-Profile anzeigen
ja bei meiner metode währe das ganze nur mit dem Windows taschenrecher nicht mit der BB.exe das müste doch gehen (der liefert doch auch nen werd zurücke.



[edit]

Habe grade noch was gefunden müste doch mit der BlitzApi gehen

http://derentwickler.de/itr/fe...id,77.html

das ist für delphi so wie ich das grade gesehen habe geht das aber
"Wenn die Menschen nur über das sprächen, was sie begreifen, dann würde es sehr still auf der Welt sein." Albert Einstein (1879-1955)
"If you live each day as if it was your last, someday you'll most certainly be right." Steve Jobs
 

Krümel

BeitragSo, Jan 28, 2007 21:16
Antworten mit Zitat
Benutzer-Profile anzeigen
hallo, Froggy!

Mein code ist im grunde sehr simpel.
1. ich öffne eine leere Datei auf c:\ mit dem namen "tmpFile01"
2. in diese Datei schreibe ich das kurze programm
f=WriteFile("c:\tmpfile02") : Writefloat f,Rechnung : close f
3. diese datei führe ich mit dem execFile - kommando aus, und das ergebnis wird in einer anderen leeren datei mit dem namen "tmpfile02" abgelegt.
4. jetzt öffne ich die "ergebnis-datei" und lese das ergebnis aus.
5. am ende werden die tmp-dateien gelöscht

Eingeproggt

BeitragSo, Jan 28, 2007 22:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie kann man in eine Floatzahl ("WriteFloat f,rechnung") eine Rechnung speichern?
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9
 

Krümel

BeitragSo, Jan 28, 2007 23:54
Antworten mit Zitat
Benutzer-Profile anzeigen
das wort "Rechnung" wird ersetzt durch die Rechenaufgabe.
Lautet die Aufgabe z.B. "1+2+3" erstellt mein Programm den Code:
f=WriteFile("c:\tmpfile02") : Writefloat f,1+2+3 : close f

5k41

BeitragMo, Jan 29, 2007 20:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
("+Rechnung+")"

fehlt dazu da nicht noch nen anführungszeichen?
Projekte:
For a better World - Gesellschaftsspiel ( 100%)

User posted image
 

Krümel

BeitragMo, Jan 29, 2007 21:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein, da fehlt nix.
s$=s$+"Writefloat("+Rechnung+")"+Chr$(10)+"CloseFile(f)"+Chr$(10)
(das sind 6 anführungszeichen , 3 öffnende und 3 schliessende)

5k41

BeitragMo, Jan 29, 2007 21:14
Antworten mit Zitat
Benutzer-Profile anzeigen
oh, stimmt, hab die zeile garnicht ganz gelesen Wink
Projekte:
For a better World - Gesellschaftsspiel ( 100%)

User posted image

StepTiger

BeitragMo, Jan 29, 2007 21:16
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Der Sinn eines Stringrechners ist, dass man 'beliebig' lange Rechenaufgaben stellen kann. Die calc.exe von Windows kann 'nur' 32 Stellen berechnen. Im zuge dessen, währe es auch sinnvoll zB die pi-Variable um ein paar Stellen zu erhöhen. Habe grad so eine pi.txt bei mir gefunden mit 88k Stellen.

edit1: Sorry, bin eben von was anderem ausgegangen. Embarassed Beitrag nicht beachten...


Absolut richtig. Auf Pibel.de kann man auch 1M Stellen runterladen, wenn ich mich nicht irre.
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer:
AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t
Gewinner: BP Code Compo #2
Π=3.141592653589793238...<--- und das aus dem kopf Laughing
Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser.

Smily

BeitragDo, Feb 01, 2007 17:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei hohen Hoch-aufgaben rechnet das Programm falsch.

konnte das Programm zumbeispiel nicht errechnen
3.52*10^21


10^10 geht auch nicht ^^

Gruß, Smily0412
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org
 

Froggy

BeitragDo, Feb 01, 2007 19:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Das liegt daran, dass 10^10 als 1.e+010, also 1*10^10 ersetzt wird.
Das e wird vom Rechner dann ignoriert (eulersche Zahl wurde schon am Anfang ersetzt) und das Plus ausgeführt.
Bleibt 1.+010, also 1+10=11

Sind ja nicht unbedingt so wichtige Rechnungen (ausser vielleicht für einen Funktionsgraphen).
 

HyDr0x

BeitragSo, Nov 25, 2007 13:22
Antworten mit Zitat
Benutzer-Profile anzeigen
StepTiger hat Folgendes geschrieben:
Absolut richtig. Auf Pibel.de kann man auch 1M Stellen runterladen, wenn ich mich nicht irre.


Wenns noch wen interresiert : http://www.apfloat.org/apfloat/ bis 61 Billionen Nachkommastellen.

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group