Sida 1 av 2

C, 24 bit i delar

Postat: 19 mars 2016, 20:57:38
av persika
Jag har en egen datatyp så här:

Kod: Markera allt

typedef unsigned short long    uInt24;    // 0-16777215,    24 bits variabel utan tecken 
Ibland vill man komma åt de olika del-byten, och då har jag denna datatyp:

Kod: Markera allt

typedef
union
  {
  uInt24 hela;  
  struct 
    {
    uInt8 byte0;
    uInt8 byte1;
    uInt8 byte2;
    }; 
  }  uInt24y;  
Det funkar bra.
Om man har en variabel:

Kod: Markera allt

uInt24y a;
När man då vill ge ett värde till mittenbyten blir det:

Kod: Markera allt

a.byte1 = 123;
Men när vill ge ett värde till hela, som "vanligt", får man skriva ex:

Kod: Markera allt

a.hela = 12345;
Det hade varit snyggare om man då kunde skriva:

Kod: Markera allt

a = 12345;
Jag testade med att ändra datatypen till:

Kod: Markera allt

typedef
union
  {
  uInt24 ;  // OBS! utan namn.
  struct 
    {
    uInt8 byte0;
    uInt8 byte1;
    uInt8 byte2;
    }; 
  }  uInt24y;  
Det går bra att kompilera.
Men det funkar ändå inte med:

Kod: Markera allt

a = 12345;
Finns det någon bra lösning på detta ?

Re: C, 24 bit i delar

Postat: 19 mars 2016, 21:13:14
av MiaM
Kan du kanske trolla lite med dels anonymous union
https://en.wikipedia.org/wiki/Union_typ ... mous_union

ihop med token concatenation
https://en.wikipedia.org/wiki/C_preproc ... catenation

Typ döp inte unionen till något alls, men använd token concatenation för att in-namnet till deklarationen både ska användas för 24-bit-typen och för 8-bit-del-typerna. Då lär du väl inte använda a.l o.s.v. utan du får väl snarast ta till t.ex. a_l eller något annat tecken som duger att ha i variabelnamn (eller inget skiljetecken alls, men det verkar farligt). Det blir lite fult att klämma ihop hela kalaset på en enda rad, men det är väl smällar man får ta.

Re: C, 24 bit i delar

Postat: 19 mars 2016, 21:28:16
av Micke_s
I c så blir det svårt att köra anonyma fält i union.

Hade det varit c++ så hade det gått att överladda tilldelningen av värdet..

Edit: variabeln hade varit ett objet...

Re: C, 24 bit i delar

Postat: 19 mars 2016, 21:55:59
av bit96
persika skrev:Jag har en egen datatyp så här:

Kod: Markera allt

typedef unsigned short long    uInt24;    // 0-16777215,    24 bits variabel utan tecken 
Vad är en 'short long'? :humm:

Re: C, 24 bit i delar

Postat: 19 mars 2016, 22:22:14
av lillahuset
Naturligtvis en kort lång. :vissla:

Re: C, 24 bit i delar

Postat: 19 mars 2016, 22:26:29
av LHelge
Unions kan vara smidigt men är de längre än en byte så får man vara försiktig. Koden blir inte portabel till en arkitektur med annan endianess.

Re: C, 24 bit i delar

Postat: 19 mars 2016, 22:31:01
av lillahuset
Nej unioner och bitfällt är två saker man ska undvika om möjligt.

Varför vill du ha en 24 bits variabel?

Re: C, 24 bit i delar

Postat: 19 mars 2016, 22:59:33
av LHelge
Detsamma gäller väl egentligen bitfält, håller man sig under 8 bitar så är det lugnt.

Re: C, 24 bit i delar

Postat: 19 mars 2016, 23:07:33
av lillahuset
Ja arkitekturer med kortare ordlängd än åtta har väl skrotats ut vid det här laget.

Men jag undrar ändå varför man vill ha 24 bits datatyper. OK, om man har väldigt lite minne och massor av variabler som ryms i 24 bit kan jag förstå.

Re: C, 24 bit i delar

Postat: 19 mars 2016, 23:59:48
av LHelge
Förutsatt att man inte slagit på 16- eller 32-bits alignment i länkfilen. Eller är det kanske på en 8-bits processor?

Re: C, 24 bit i delar

Postat: 20 mars 2016, 00:05:47
av lillahuset
Vem vet?

Re: C, 24 bit i delar

Postat: 20 mars 2016, 14:36:47
av persika
Glömde att säga att jag använder PIC16F1825 och MPLAB 8.88 med friversionen av Hitech-C, (deoptimiserade versionen...)


>Vad är en 'short long'?

Det är 24-bitsvariabel utan tecken, enligt Hitech-C.


>Men jag undrar ändå varför man vill ha 24 bits datatyper.

I detta fall har jag ett 16-bits värde från Timer1 som jag vill multiplicera med 0,7 för att passa till i senare del av programmet.
För att slippa använda flyttal tar jag då multiplicerar med 179 (8bitar) och sen dividerar med 256.
När man då multiplicerar 16-bitar med 8-bitar så kan resultat bli ända upp till 24-bitar.
För att sen dividera med 256 är det enklaste att bara hämta byte1 och byte2 och låta bli byte0.
Annars kan man ju använda / eller högerskift >> åtta gånger.

Tack för svar på själva frågan, verkar inte som det finns nån riktigt bra lösning, när det gäller C,
så jag får väl använda a.hela när jag ska tilldela alla tre byte på en gång.

Re: C, 24 bit i delar

Postat: 20 mars 2016, 15:01:47
av lillahuset
Jag skulle definiera en array med tre byte. Peka med en short long pekare på den variabeln och peka på mittenbyten med en short pekare.

Kod: Markera allt

uint8_t variabel[3];
short long *slpekare = (short long *) variabel;
uint16_t *pekare = (uint16_t *) variabel[1];
Eller något i den stilen.

Re: C, 24 bit i delar

Postat: 20 mars 2016, 16:03:23
av Icecap
"Det är 24-bitsvariabel utan tecken, enligt Hitech-C."

Enl. GCC finns den kombination inte - men jag ser nyttan i vissa fall.

Re: C, 24 bit i delar

Postat: 20 mars 2016, 16:26:31
av lillahuset
Det är inte standard C men kan ju vara användbart ändå. Eller också är det så att personalen på Hitech druckit för mycket XXXX.