/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
Bech_bb 500
kyllekylle 500
jdjespers.. 500
gibson 300
scootergr.. 300
molokyle 287
10  strarup 270
hvordan samler jeg to registre til en int
Fra : finn knussen


Dato : 29-05-06 09:15

hvis jeg har i reg1 = 0x03 reg2 = 0xFF hvordan samler jeg dem til en
int = 1023 ??


 
 
Bertel Lund Hansen (29-05-2006)
Kommentar
Fra : Bertel Lund Hansen


Dato : 29-05-06 09:27

finn knussen skrev:

> hvis jeg har i reg1 = 0x03 reg2 = 0xFF hvordan samler jeg dem til en
> int = 1023 ??

reg = reg1*0x100+reg2;

--
Bertel
http://bertel.lundhansen.dk/      http://fiduso.dk/

finn knussen (29-05-2006)
Kommentar
Fra : finn knussen


Dato : 29-05-06 10:05

det virker bare tak for det

Kan du fortælle mig hvorfor

ADC_VALUE = ADRESL;
ADC_VALUE += (ADRESH << 8);

ikke giver det samme som (reg1*0x100)+reg2 ??


Bertel Lund Hansen (29-05-2006)
Kommentar
Fra : Bertel Lund Hansen


Dato : 29-05-06 10:25

finn knussen skrev:

> Kan du fortælle mig hvorfor

> ADC_VALUE = ADRESL;
> ADC_VALUE += (ADRESH << 8);

> ikke giver det samme som (reg1*0x100)+reg2 ?

Næ, ikke uden at kende koden til bunds. Hvis nogle af de variable
er af typen char, kan de kun rumme 8 bit.

--
Bertel
http://bertel.lundhansen.dk/      http://fiduso.dk/

Eric Jensen (29-05-2006)
Kommentar
Fra : Eric Jensen


Dato : 29-05-06 10:30


"finn knussen (slet 4XNO7)" <finn@4XNO7familie.tele.dk> skrev i en
meddelelse news:11488937350.840224302355772@dtext.news.tele.dk...

> Kan du fortælle mig hvorfor
>
> ADC_VALUE = ADRESL;
> ADC_VALUE += (ADRESH << 8);
>
> ikke giver det samme som (reg1*0x100)+reg2 ??
>

int _tmain(int argc, _TCHAR* argv[]) {
unsigned char reg1 = 0x03, reg2 = 0xFF;
int result = (reg1 << 0x08) + reg2;
std::cout << "result: " << result << std::endl;
system("pause");
return 0;
}

Outputs:
result: 1023
Tryk på en vilkårlig tast for at fortsætte . . .

Iøvrigt skal du ikke bruge "(reg1*0x100)+reg2" den formel er en
matematikkers metode, og den kræver flere cpu instruktioner at udføre end
bitshift metoden.

Hvis det er en ip addresse du prøver at samle kan det gøres sådan her:
int _tmain(int argc, _TCHAR* argv[]) {
unsigned char a = 127, b = 0, c = 0, d = 1; // 127.0.0.1
unsigned long networkAddr = (a << 24) + (b << 16) + (c << 8) + (d << 0);
std::cout << "127.0.0.1 is equal to this network address: " << networkAddr
<< std::endl;
system("pause");
return 0;
}

//eric



Bertel Brander (29-05-2006)
Kommentar
Fra : Bertel Brander


Dato : 29-05-06 18:29

Eric Jensen wrote:
>
> Iøvrigt skal du ikke bruge "(reg1*0x100)+reg2" den formel er en
> matematikkers metode, og den kræver flere cpu instruktioner at udføre end
> bitshift metoden.

Hvordan ved du at det kræver flere instruktioner?
Der er ingen garanti for at den laver det med *0x100 med en
gange operation, der er heller ingen garanti for at den
laver << 8 med bitshift.

> Hvis det er en ip addresse du prøver at samle kan det gøres sådan her:
> int _tmain(int argc, _TCHAR* argv[]) {
> unsigned char a = 127, b = 0, c = 0, d = 1; // 127.0.0.1
> unsigned long networkAddr = (a << 24) + (b << 16) + (c << 8) + (d << 0);
> std::cout << "127.0.0.1 is equal to this network address: " << networkAddr

Det forudsætter at int er mindst 32 bit på din platform.

--
Absolutely not the best homepage on the net:
http://home20.inet.tele.dk/midgaard
But it's mine - Bertel

Ukendt (29-05-2006)
Kommentar
Fra : Ukendt


Dato : 29-05-06 19:33

>> unsigned long networkAddr = (a << 24) + (b << 16) + (c << 8) + (d <<
>> 0);
>
> Det forudsætter at int er mindst 32 bit på din platform.
>

Finn,

a,b,c,d er chars
Hvad sker der når man skifter en char 8 bit op? Hvad er der så tilbage ?
Må man det ? JA (*1)

Må man skifte en char 24 bit op?
Well ... her har Eric en pointe

Forklaringen er

-Compileren ser at der skal laves en udregning med variablen c.
-Så beslutter den sig for at lave en "integral promotion" hvilket vil sige,
at den har lov til at udføre sine udregninger i en register størrelse som
den holder særlig meget af, og dette er "int"
-Derefter udfører den skifte operationen (8,16 eller 24 bits)

På denne måde kan du se, at hvis integer størrelsen er 16 bits, skifter du
bittene flere pladser op, end der er bits i variablen du opererer på. Om du
i så tilfælde er garanteret at resultatet bliver nul, eller om du laver
"undefined behaviour" således at compileren siges at opføre sig ok,
ligemeget hvilket resultat den når frem til, kan nogle af de andre sikkert
uddybe.
Hvis integer størrelsen er 32 bits vil det virke korrekt.

Hvis programmet skal bruges på platforme hvor integer størrelsen er ukendt,
eller hvis du bare synes at det er fedt at dette kode SKAL virke alle
steder, kan du vælge at caste explicit til typen ulong.

unsigned long networkAddr = (((unsigned long)a) << 24) ....

(*1) Jeg mener at størrelsen af int er garanteret til at være større end
char , så hvis char er 8 bit skal int være mindst 16 bit, så derfor SKAL det
virke at skifte en char 8 pladser op. Might be wrong !?!?

N.B. Bare fordi det ser ud til at virke på din platform, så kan der stadig
være grund til at lave castet. Jeg opgraderede engang en Hitachi H8 compiler
(embedded 8 bit), og derefter var der noget kode der ikke virkede pga det
manglende cast.

tpt




Bertel Brander (29-05-2006)
Kommentar
Fra : Bertel Brander


Dato : 29-05-06 21:01

Troels Thomsen wrote:
> (*1) Jeg mener at størrelsen af int er garanteret til at være større end
> char , så hvis char er 8 bit skal int være mindst 16 bit, så derfor SKAL det
> virke at skifte en char 8 pladser op. Might be wrong !?!?

En int er mindst 16 bit, en short også 16 bit, og long er mindst 32 bit
En char er mindst 8 bit, men en char kan også være 16 eller 32 bit.

Der gælder dog:

8 <= sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

--
Absolutely not the best homepage on the net:
http://home20.inet.tele.dk/midgaard
But it's mine - Bertel

Igor V. Rafienko (29-05-2006)
Kommentar
Fra : Igor V. Rafienko


Dato : 29-05-06 21:08

[ Bertel Brander ]

[ ... ]

> Der gælder dog:
>
> 8 <= sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)


Nei, da sizeof(char) == 1. Alltid.





ivr
--
"...but it's HDTV -- it's got a better resolution than the real world."
       -- Fry, "When aliens attack"

Bertel Brander (29-05-2006)
Kommentar
Fra : Bertel Brander


Dato : 29-05-06 21:35

Igor V. Rafienko wrote:
> [ Bertel Brander ]
>
> [ ... ]
>
>> Der gælder dog:
>>
>> 8 <= sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
>
>
> Nei, da sizeof(char) == 1. Alltid.

Ups, det jeg mente var at en char er mindst 8 bit.

Så det var nok dette jeg mente:
8 <= bitsof(char) <= bitsof(short) <= bitsof(int) <= bitsof(long)

Men der er ingen bitsof i C eller C++

--
Absolutely not the best homepage on the net:
http://home20.inet.tele.dk/midgaard
But it's mine - Bertel

Igor V. Rafienko (29-05-2006)
Kommentar
Fra : Igor V. Rafienko


Dato : 29-05-06 21:47

[ Bertel Brander ]

[ ... ]

> > Nei, da sizeof(char) == 1. Alltid.
>
> Ups, det jeg mente var at en char er mindst 8 bit.


:)


> Så det var nok dette jeg mente:
> 8 <= bitsof(char) <= bitsof(short) <= bitsof(int) <= bitsof(long)
>
> Men der er ingen bitsof i C eller C++


Såklart er det det -- sizeof(T)*CHAR_BITS er antall bits i en type T.





ivr
--
"...but it's HDTV -- it's got a better resolution than the real world."
       -- Fry, "When aliens attack"

Ukendt (30-05-2006)
Kommentar
Fra : Ukendt


Dato : 30-05-06 17:38



Skal det gå op i 8 ?


tpt



Bertel Brander (30-05-2006)
Kommentar
Fra : Bertel Brander


Dato : 30-05-06 22:15

Troels Thomsen wrote:
> Skal det gå op i 8 ?

Nej. Man kan godt have bytes på f.ex. 9 eller 15 bit,
men det er ikke ret almindeligt.

Der findes DSP'er der kun kan bruge 32 bit data typer,
så de har 32 bit char, short, int og long. Det er
lovligt ifølge standarden.

/* Jeg synes at tdc's nyhedsgruppe server bliver mere
og mere upålidelige, jeg har svaret én gang for flere
timer siden, men svaret er ikke dukket op. Så jeg tillader
mig at prøve igen */

--
Absolutely not the best homepage on the net:
http://home20.inet.tele.dk/midgaard
But it's mine - Bertel

Arne Vajhøj (29-05-2006)
Kommentar
Fra : Arne Vajhøj


Dato : 29-05-06 22:19

Eric Jensen wrote:
> Iøvrigt skal du ikke bruge "(reg1*0x100)+reg2" den formel er en
> matematikkers metode, og den kræver flere cpu instruktioner at udføre end
> bitshift metoden.

Det er ikke nogen naturlov.

Compilere bliver bedre til at optimere og CPU'er får mere og
mere hardwired funktionalitet.

Jeg vil kalde det bad practice at lave den slags
optimeringer.

Programmøren skal lave let læselig kode. Compileren
skal generere den hurtigst mulige kode.

I kritiske sektioner af CPU intensiv kode kan man
evt. lave en specifik optimering efter at have verificeret
at det faktisk gør en forskel.

Men det bør være undtagelsen ikke reglen.

Arne

PS: I det konkrete tilfælde synes jeg faktisk at shift
virker mere naturlig og letlæselig end multiplikation,
men det er så en helt anden sag.


Bertel Brander (29-05-2006)
Kommentar
Fra : Bertel Brander


Dato : 29-05-06 21:01

finn knussen (slet 4XNO7) wrote:
> det virker bare tak for det
>
> Kan du fortælle mig hvorfor
>
> ADC_VALUE = ADRESL;
> ADC_VALUE += (ADRESH << 8);
>
> ikke giver det samme som (reg1*0x100)+reg2 ??

Jeg har postet dette én gang før, men prøver igen:

En logisk forklaring kunne være at cpu'en har
8 bit int, hvilket ikke er "lovligt" ifølge standarden,
men det findes på nogle små micro processorer.

Eller at den trunkerer "ADRESH << 8" til 8 bit
inden +=, hvilket heller ikke er "lovligt".

Det er muligt at den opfatter 0x100 som en
16 bit størrelse, derved vil det komme til at
virke.

--
Absolutely not the best homepage on the net:
http://home20.inet.tele.dk/midgaard
But it's mine - Bertel

Morten M. Jørgensen (27-07-2006)
Kommentar
Fra : Morten M. Jørgensen


Dato : 27-07-06 07:45

> Kan du fortælle mig hvorfor
>
> ADC_VALUE = ADRESL;
> ADC_VALUE += (ADRESH << 8);
>
> ikke giver det samme som (reg1*0x100)+reg2 ??

Kunne jo tydeligvis ligne en 8bit MCU kode. Hvis det er tilfældet så prøver
på at bitskifte et 8bit register 8 gange op, det går ikke uden casting.

ADC_VALUE = ADRESL;
ADC_VALUE +=(unsigned int) (ADRESH << 8);

eller:


ADC_VALUE = ADRESH;
ADC_VALUE <<= 8;
ADC_VALUE +=ADRESL;

--
Morten



Ukendt (28-07-2006)
Kommentar
Fra : Ukendt


Dato : 28-07-06 00:03

>
> Kunne jo tydeligvis ligne en 8bit MCU kode. Hvis det er tilfældet så
> prøver på at bitskifte et 8bit register 8 gange op, det går ikke uden
> casting.
>
> ADC_VALUE = ADRESL;
> ADC_VALUE +=(unsigned int) (ADRESH << 8);
>

Castet står forkert i dit eksempel. Jeg tror du mener
ADC_VALUE +=(((unsigned int) ADRESH) << 8);


Det er svjv _udefineret_ hvad der sker når man skifter højere op end
bitbredden logisk tillader
Jeg har brugt en embedded H8 compiler hvorpå det virkede, og i næste version
virkede det ikke.
Svjv kan man ikke kalde den ene compiler version defekt, netop fordi det er
udefineret hvad der sker.
Det vil dog være garanteret at virke på alle compilere hvis man caster
først, så det er unægteligt en god ide.

tpt



Søg
Reklame
Statistik
Spørgsmål : 177564
Tips : 31968
Nyheder : 719565
Indlæg : 6408970
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste