Forum: Mikrocontroller und Digitale Elektronik Mathematisches dividieren elegant lösen


von C. H. (hedie)


Lesenswert?

Hallo zusammen

Ich stehe vor folgendem Problem:

Gegeben ist ein String mit folgendem Format:

00847.9394

Folgendes muss damit gemacht werden:

Die ersten drei Ziffern entfernen und speichern in sagen wir mal x

-> 008 in x speichern (Das ist noch kein Problem!)

Dann bleibt uns das übrig:

47.9394

Dieser String wird als Kommazahl betrachtet also 47,9394 und muss durch 
60 geteilt werden. Das ergebnis nennen wir mal y

Schlussendlich muss x zu y addiert werden.

Die Frage ist nun, wie teile ich 47.9394 am elegantesten durch 60.
Ich benötige schlussendlich keine float oder double variable sondern 
wieder einen String.

Von daher möchte ich wenn möglich float oder double vermeiden.

Kennt hier jemand einen gängige Methode, welche am einfachsten und 
Ressourcen sparendsten zum Ziel kommt?

Danke schonmal

von Michael (Gast)


Lesenswert?

Claudio Hediger schrieb:
> Die Frage ist nun, wie teile ich 47.9394 am elegantesten durch 60.
Sag' doch gleich, dass du eine Position aus einem NMEA-Sentence 
zerpflücken willst.
Wenn du nicht mit Zahlen rechnen möchtest, erklär doch mal, wie die 
Divisionsregel für Strings definiert ist ;-)

von Dussel (Gast)


Lesenswert?

Ist der Dividend, also in dem Fall die 60 fest vorgegeben? Muss also 
immer durch 60 und nicht durch eine andere Zahl geteilt werden? Dann ist 
ein Ansatz, zu multiplizieren. Durch 60 teilen ist das gleiche, wie mit 
1/60 zu multiplizieren. Um dafür einen einfachen Multiplizierer 
verwenden zu können, kannst du das mit einer Zweierpotenz 
multiplizieren, also zum Beispiel 1/60*1024=17,07. Damit multiplizierst 
du und teilst das Ergebnis durch 1024. Da 1024 eine Zweierpotenz ist, 
geht das dividieren ziemlich schnell.
Als Beispiel:
2362/60=39,367
(2362*17)/1024=39,212

Die andere Aufgabe ist jetzt noch, die Kommazahl umzuwandeln.

von g457 (Gast)


Lesenswert?

> Von daher möchte ich wenn möglich float oder double vermeiden.

Festkommaarithmetik wenns unbedingt sein muss.

> Kennt hier jemand einen gängige Methode, welche am einfachsten [..]

ftoa, strof, sscanf und wie sie nicht alle heissen, sogar schon fertig 
und gut getestet.

> [..] und Ressourcen sparendsten zum Ziel kommt?

Dann halt doch wieder Festkommaarithmetik wenns unbedingt sein muss.

von C. H. (hedie)


Lesenswert?

Michael schrieb:
> Claudio Hediger schrieb:
>> Die Frage ist nun, wie teile ich 47.9394 am elegantesten durch 60.
> Sag' doch gleich, dass du eine Position aus einem NMEA-Sentence
> zerpflücken willst.
> Wenn du nicht mit Zahlen rechnen möchtest, erklär doch mal, wie die
> Divisionsregel für Strings definiert ist ;-)

Jep es ist ein NMEA sentence... Ich könnte ja auch auf OSP umschalten 
und dann die Binärdaten in ein Struct schaufeln, aber bin mit der 
Bedienung des Moduls noch nicht so vertraut und bin froh dass es jetzt 
mal stabil läuft.

Deshalb wurstle ich lieber im uC mit den Strings als das ich das Modul 
umkonfiguriere...

Ist mir schon klar, dass man Strings nicht dividieren kann.
Aber ich dachte, eventuell gibts ne möglichkeit nur die vorkomma Zahl zu 
dividieren und dann mit der dividierten nachkommazahl zu kombinieren.

Weil die Funktionen für String to Double und wieder Zurück benötigen 
halt schon arg viel platz.

Und dies nur um solch eine poplige Zahl zu dividieren.

Ich dachte jemand kennt einen Weg dies elegant und einfach zu lösen.

von C. H. (hedie)


Lesenswert?

Dussel schrieb:
> Ist der Dividend, also in dem Fall die 60 fest vorgegeben? Muss also
> immer durch 60 und nicht durch eine andere Zahl geteilt werden?

Ja ist immer 60.

........


Danke für eure Hinweise... Werde dies mal versuchen.

Bin jedoch immernoch für Vorschläge offen :)

von C. H. (hedie)


Lesenswert?

So habe nun folgende Idee...

47.9394 wird mit 10000 Multipliziert

Dies ergibt 479394 (also einen unsigned long)

Diesen teile ich durch 6

Dies ergibt 79899 und entspricht genau der nachkommastelle

Da 47.9394 / 60 = 0.79899 ergibt.

Somit muss ich lediglich die 008 also 8 in ein Zeichen umwandeln einen
punkt setzten und nun die errechnete nachkommastelle 79899 dazu setzen.

Ich denke dies ist am einfachsten um den Long zu umgehen.

von wire (Gast)


Lesenswert?

Ist doch nun wirklich nicht schwer. Es sind alle Möglichkeiten als 
Antwort erschienen, jetzt brauchst du nur noch den Punkt im Kopf 4 
Stellen nach rechts schieben, das Ganze in einen int32 packen, 
entsprechend multiplizieren und du hast dein Ergebnis.

von Michael (Gast)


Lesenswert?

Claudio Hediger schrieb:
> 47.9394 wird mit 10000 Multipliziert

Strings kannst du nicht multiplizieren.

Wenn du Float vermeiden möchtest und dir sicher bist, dass jedes GPS was 
du anschließen möchtest, die Koordinaten auf 1/10000 Minuten ausgibt 
(das tun lange nicht alle), dann reicht es, den Dezimaltrenner einfach 
rauszuschmeißen.

von Mr.T (Gast)


Lesenswert?

Michael schrieb:
> Claudio Hediger schrieb:
>> 47.9394 wird mit 10000 Multipliziert
>
> Strings kannst du nicht multiplizieren.

Er meint wohl, dass er einfach den Punkt entfernt und aus dem Teilstring 
"47" und dem Teilstring "9394" einen String "479394" bastelt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.