Double zu int - Zahl teilen und umwandeln

Hallo,

ich habe ein kleines Problem. Ich bekomme über meine Serielle Schnittstelle eine Zahl mit 8Byte.

Das ist ein Beispiel einer Übertragung:
00 00 00 7D 2B D5 A7 60 <- HEX
537606334304 <- DEC

Der "reale" wert wäre 5376,06334304. Also eine Zahl mit 8 Nachkommastellen.

Jetzt kommt mein Problem: Ich bräuchte eigentlich nur die Vorkommastellen - maximal 1-2 Nachkommastellen. Diese Zahl sollte dann auch ohne Probleme in eine INT passen.

Ich habe schon versucht die double / 100000 zu teilen und danach auf INT zu casten. Funktioniert nicht. Direkt auf INT casten geht auch nicht. Er nimmt immer nur die ersten 4 Byte ( 2B D5 A7 60 ).

Der Grund ist, dass ich so eine Große Zahl nirgendwo ausgeben kann. Thingspeak z.B. lässt maximal eine INT zu.

Grüße
Daniel

Eher nicht.
Ausgehend von Deinem Ausgangspost:

wäre bei einer Verschiebung des Komma mit *100 int überschritten.

Woher willst Du denn wissen, an welcher Stelle das Komma ist?

Gruß Tommy

Wenn er einen long long bekommt bei dem die letzten 8 das NK darstellen ist das doch kein Problem.

Immer 8 Nachkommastellen bei kWh. Die leg ja ich fest wie viele Nachkommastellen die Zahl hat.

Das Problem ist und bleibt das selbe. Zur Ausgabe benötige ich eine maximal 32bit große Zahl.

Therorie:
(537606334304 / 100000000) nach int = 5376

Realität:
00 00 00 7D 2B D5 A7 60 nach int = 2B D5 A7 60

Sollte eigentlich kein Problem sein - wenn die Nachkommastellen eh' nicht interessieren.
Hier durch 100000 geteilt.

22:25:34.834 -> shortValue: 5376063

wird erzeugt durch diesen Code (auf Uno):

  uint64_t value = 0x0000007D2BD5A760LL;
  uint32_t shortValue;

  shortValue = value / 100000LL;
  Serial.print("shortValue: ");
  Serial.println(shortValue);

Nachtrag:
Die Theorie in die Praxis überführen:

shortValue = value / 100000000LL;
22:31:36.222 -> value: 5376
1 Like

Da war jemand mit dem Code schneller :wink: Und ich sag noch long long...

Soll nicht wieder vorkommen :wink:

Das Problem ist, dass long long in der Arduino-Referenz gar nicht und sonst wohl auch eher selten beschrieben ist.
Die 8 Byte von der Schnittstelle in die Variable zu drücken überlasse ich Daniel selbst.


Gruß Walter

Danke werde ich testen.

Muss ich es anstatt Double dann uint64_t nennen ?

Die Double var wird übrigens per shifting gefüllt. Also Byte für Byte aus einem array

Versucht habe ich:


Double value = 0000007D2BD5A760;
Int shortValue;

  shortValue = value / 100000;
  Serial.print("shortValue: ");
  Serial.println(shortValue);

Das funktioniert auf jeden Fall nicht .

Ja. double kommt aus der Familie der floating point, während uint64_t ... na ja, Du weißt schon; der Name spricht ja Bände.

Nochmal Edit: Bau Dir doch eine Union, dann kannst Du Byte für Byte in den Array kippen und nachher mit value weiterarbeiten.

union myLongLong {
  uint8_t bytes[8];
  uint64_t value;
};

Nochmal!
Was denkst Du denn, wo die restlichen Bits bleiben, wenn der long long ausgenutzt wird?

Wohl wahr. Da bin auch ich zu kurz gesprungen.
Um die unteren 32 Bit komplett loszuwerden, müsste man schon durch
4294967296LL // 0x100000000
teilen, was deutlich mehr ist als die 8 Nachkommastellen.

Wieso hat ein long long als Ganzzahlwert Nachkommastellen?

Gruß Tommy

Hab ich nicht geschrieben.
Payload: 8 byte.
In der Payload werden 8NK abgebildet.
Ich vermeide sowas, aber es funktioniert.

So bevor hier was schief läuft :wink:

so kommen die Daten in meine 64bit variable:

value = (var[0] << 56 | var[1] << 48 | var[2] << 40 | var[32] | var[4] << 24 | consumption[5] << 16 | var[6] << 8 | var[7]);

Noch eine Frage zu deiner Schreibweise: du hast davor 0x und hinten LL. Genauso bei der Zahl durch die du teilst. Was hat es damit auf sich? Muss ich meine u_int64_t auch damit am Anfang und am Ende befüllen? oder wird das automatisch angehängt?

Ist kein double :wink: (hoffentlich!)
Aber 8byte payload...

Hab es jetzt als u_init64_t versucht. Genau das gleiche. Er streicht die 4 Byte weg wie davor auch.

Ich versuche es nochmal einfacher zu sagen - nicht das wir hier aneinander vorbei reden.

Ich will im Endeffekt das Dezimalergebnis kürzen und die verkürzte Zahl in eine 8Byte Variable speichern. Bei 4 oder 5 stellen sollte das ja gehen.

Wie wird das eigentlich definiert was bzw wo ein Koma sitzt?
537606334304 = 00 00 00 7D 2B D5 A7 60
5376,06334304 = 00 00 00 7D 2B D5 A7 60

da gibt es doch keinen Unterschied oder? Die Hex bleibt gleich. Ich will aber mit dem Dezimalergebnis weiterarbeiten und NICHT mit der Hex.

Wie kommen denn die 8 Byte auf Deinem Sendesystem zu Stande?
Gemeint ist nicht die eine Zeile mit den Shift der 8 Byte, sondern die Quelle dieser 8 Byte als Code.

Gruß Tommy

Das ist ein Zähler der die Ausgibt.

Ein Zähler kann keine Nachkommastellen haben. Irgendwie erzählst Du Unsinn.

Gruß Tommy