|
| 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 (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
| |
|
|