Forum: Compiler & IDEs Wert > 255 in Array


von PeterM (Gast)


Lesenswert?

Hallo,

wenn ich ein

uint8_t inhalt[8][8];

Array anlege.

Ich habe z.b. einen String Name in inhalt[0]
den Vornamen in inhalt[1]

Funktioniert soweit.

Jetzt möchte ich z.b. einen Betrag in inhalt[2] ablegen

z.b. 123,67 €

später möchte ich dann 0,47€ davon abziehen, wie soll ich vorgehen um 
den Betrag im Array zu speichern?

die Cent in inhalt[2][0]
die Euro in inhalt[2][1]
?

wenn ich aber Euro=inhalt[2][0]+inhalt[2][1] mache habe ich ja ein 
problem beim zurückschreiben. Wie gehe ich da am besten vor?

von Peter II (Gast)


Lesenswert?

Speicher es doch als Cent in einem uint16_t. Dann kannst du auch damit 
rechnen.

von Egal (Gast)


Lesenswert?

Warum kein Array of float/double oder wenns sein muss ein uint16_t und 
immer in Cent rechnen?

von Michael S. (mikel_x)


Lesenswert?

Das Problem hast du schon vorher, weil du die Eigenarten der Datentypen 
nicht verstehst. Mach dich erstmal schlau, welche Art von Zahlen in 
welche Datentypen passen... danach geht der Kurs weiter... ;-)

von PeterM (Gast)


Lesenswert?

Mir ist schon klar das das uint8 nur bis FF geht.

Das Problem ist ich bekomme die Daten seriell im format 0xFF 0xFF 0xFF 
0xFF ...

kann ich 0xFF 0xFF in ein uint16 0xFFFF umwandeln?

von Peter II (Gast)


Lesenswert?

PeterM schrieb:
> kann ich 0xFF 0xFF in ein uint16 0xFFFF umwandeln?

ja

uint16_t x = 0xFF<<8 | 0xFF;

von PeterM (Gast)


Lesenswert?

Aaah ok, verstanden, vielen Dank :)

von Egal (Gast)


Lesenswert?

1
union {
2
 uint8_t 8b[2];
3
 uint16_t 16b;
4
} blub;
5
6
blub.8b[0]  = 0xFF;
7
blub.8b[0]  = 0xFF;
8
9
printf("%d", blub.16b);

Allerdings musst Du jetzt noch sämtlichen Dummfug in nachfolgenden 
Postings ignorieren können, der Dir sagt warum das böse ist.

von Egal (Gast)


Lesenswert?

muss natürlich
1
blub.8b[0]  = 0xFF; 
2
blub.8b[1]  = 0xFF;

sein.

von Peter II (Gast)


Lesenswert?

Egal schrieb:
> Allerdings musst Du jetzt noch sämtlichen Dummfug in nachfolgenden
> Postings ignorieren können, der Dir sagt warum das böse ist.

und hier ist er schon.

verwende kein Union - es bringt keinen Vorteil und den Nachteil das das 
Ergebnis von der Plattform und dem Compiler abhängt.

von Michael S. (mikel_x)


Lesenswert?

Wenn du Zeit hast, sie getrennt in ein Array zu schieben, kannst du sie 
auch gleich zusammenführen:

Mach ein Array mit Fließkommadatentyp und schreib dort rein 
C(n)=a+b/100, wobei a die Ganzzahl und b die Nachkommazahl im INT-Format 
sind, die du beim Empfang in einen Zwischenpuffer bzw. Puffer-Array 
schreibst... Dann kannst du mit deinen Beträgen auch weiterrechnen, wie 
es dir beliebt...

von Stefan E. (sternst)


Lesenswert?

Michael Sch. schrieb:
> Mach ein Array mit Fließkommadatentyp und schreib dort rein
> C(n)=a+b/100, wobei a die Ganzzahl und b die Nachkommazahl im INT-Format
> sind

Gleitkomma ist hier reichlich unangebracht und macht nur Ärger. 
Geldbeträge sind DER klassische Anwendungsfall für Festkomma. Man nimmt 
einen Integer-Typ und betrachtet den Inhalt als Cent-Betrag.

von Michael S. (mikel_x)


Lesenswert?

ja, Festkomma... meinte ich auch... muss nebenher auf meine Spargel 
aufpassen, daß sie nicht verkochen... ;-)

von PeterM (Gast)


Lesenswert?

Hallo,

ok, ahbe es hinbekommen, klar wird dann in Cent gerechnet

zurück umwandeln mach ich mit:

inhalt[2][0]=(uint8_t)Betrag;
inhalt[2][1]=(uint8_t)(Betrag >> 8);

Danke

von Benedikt (Gast)


Lesenswert?

Das ist aber alles mehr als umständlich...
1
struct inhalt_t {
2
    char[8] Name;
3
    char[8] vorname;
4
    uint16_t betrag;
5
    // weitere Felder
6
}
halte ich fürs wesentlich eleganter, falls ich richtig verstehe was du 
da vorhast.

So beschreibst du aber nur den Datentyp, die tatsächliche Struktur im 
Speicher wirds dann mit:
1
struct inhalt_t inhalt;

Dann schreibst du einzelne Zeichen in den strings so:
1
inhalt.Name[index] = whatever;
Dran denken, das die string-Funktionen der Standardbibliothek 
NULL-terminierte strings erwarten!

Der Betrag ist dann wie oben erläutert so zu erreichen:
1
inhalt.betrag = foo;
2
3
//oder auch so falls die beiden bytes nacheinander ankommen
4
extern uint8_t foo, bar;
5
inhalt.betrag = (uint16_t) foo;
6
inhalt.betrag |= (uint16_t) (bar << 8);

von Peter II (Gast)


Lesenswert?

Benedikt schrieb:
> Das ist aber alles mehr als umständlich...
> struct inhalt_t {
>    char[8] Name;
>    char[8] vorname;
>    uint16_t betrag;
>    // weitere Felder
>}
> halte ich fürs wesentlich eleganter, falls ich richtig verstehe was du
> da vorhast.

und wieder nicht portabel. Nicht mal der Compiler muss es richtig 
umsetzen, weil das verhalten nicht definiert ist. Und auf Big/Little 
Endian liefert es auch was anders als erwartet.

Union sind nicht dafür gemacht und sollten auch nicht dafür missbraucht 
werden!

von Benedikt (Gast)


Lesenswert?

Peter II schrieb:
> Benedikt schrieb:
>> Das ist aber alles mehr als umständlich...
>> struct inhalt_t {
>>    char[8] Name;
>>    char[8] vorname;
>>    uint16_t betrag;
>>    // weitere Felder
>>}
>> halte ich fürs wesentlich eleganter, falls ich richtig verstehe was du
>> da vorhast.
>
> und wieder nicht portabel. Nicht mal der Compiler muss es richtig
> umsetzen, weil das verhalten nicht definiert ist. Und auf Big/Little
> Endian liefert es auch was anders als erwartet.
>
> Union sind nicht dafür gemacht und sollten auch nicht dafür missbraucht
> werden!

Das ist ja auch keine union! Mein Code wäre sicher problematisch wenn er 
einfach ein
1
(uint8_t*) &inhalt
 macht und dann alles in einem Schwung irgendwo hin sendet (wg dem 
uint16_t).
Ohne meintest du was anderes?

von Peter II (Gast)


Lesenswert?

Benedikt schrieb:
> Das ist ja auch keine union! Mein Code wäre sicher problematisch wenn er

oh sorry, ist schon spät.

Ich nehme alles zurück und gehe ins Bett...

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.