Cześć.
Chciałem Was prosić o pomoc w rozwiazaniu takiego problemu.
Otóż mam czujnik temperatury, który podaje wynik z uzupełnieniem do dwóch.
Odczytuje ten wynik i potrzebuję podzielić tą wartość przez dwa.
I tu zaczynają sie schody, bo jeśli mam np dziesiętnie -6 (a hex 0xFA) to po podzieleniu przez 2 wcale nie dostaję -3 (0xFD) tylko zupełnie inną liczbę. Jest tak jakby kompilator miał zamiast -6 liczbę dodatnią 250 i dopiero tą liczbę dzieli przez 2.
Jest to kompilator C dla AVR i zmienna jest deklarowana jaku signed char.
operacje na liczbach w zapisie z uzupełnieniem do dwóch
Re: operacje na liczbach w zapisie z uzupełnieniem do dwóch
a jakiego typu jest wynik? też signed char?slawek55 pisze:Jest to kompilator C dla AVR i zmienna jest deklarowana jaku signed char.
to akurat z VC++
Kod: Zaznacz cały
signed char schValue = -30;
signed char schResult_Signed = schValue / 3;
printf ("rsig = %d (%02X) \n", schResult_Signed, schResult_Signed );
unsigned char schResult_Unsigned = schValue / 3;
printf ("runs = %d (%02X) \n", schResult_Unsigned, schResult_Unsigned );
Kod: Zaznacz cały
rsig = -10 (FFFFFFF6)
runs = 246 (F6)
problem jest chyba w złych typach danych lub braku rzutownia na signed char
Czeć sorry że tak póno odpowiadam, pewne kłaopoty z sieciš.
Dowiedziałem sie ze moj kompilator obługuje ze znakiem tylko int , char zawsze unsigne.
Szukałem algorytmow obliczeń na zmiennych jednobajtowych w kodzie U2 ale nie znalazłem nic, jeli macie cos to podrzucie.
Przedstawiam moj kod jest to Obsługa odczytu DS1820 (nie jest to moj pomysł tylko z sieci).
signed char Tb;
signed int Tm;
unsigned char Tb01,minus,;
char Str[9];
Tb=(signed char)Str[0]; // w tym rejestrze jest wartiosc tem w kodzie U2
Tb=Tb/2;
Tb01=((Str[7]-Str[6])*10)/Str[7];
Tm=(Tb*100)+(Tb01*10)-25;
if((Tm&0x8000)==0x800)
{ //liczba ujena
minus=1;
Tm=~Tm;
Tm=Tm+1;
}
else minus=0;
Str[0]=0;
while(Tm>99){ Tm=Tm-100; Str[0]++; } //wyliczenie czeci calokwitej
Tb01=(char)Tm; //reszta to cyfra po przecinku
Tb01=Tb01/10; //tylko jedno miejsce po przecinku
jeli macie jaki lepszy kod to będę wdzięczny.
Dowiedziałem sie ze moj kompilator obługuje ze znakiem tylko int , char zawsze unsigne.
Szukałem algorytmow obliczeń na zmiennych jednobajtowych w kodzie U2 ale nie znalazłem nic, jeli macie cos to podrzucie.
Przedstawiam moj kod jest to Obsługa odczytu DS1820 (nie jest to moj pomysł tylko z sieci).
signed char Tb;
signed int Tm;
unsigned char Tb01,minus,;
char Str[9];
Tb=(signed char)Str[0]; // w tym rejestrze jest wartiosc tem w kodzie U2
Tb=Tb/2;
Tb01=((Str[7]-Str[6])*10)/Str[7];
Tm=(Tb*100)+(Tb01*10)-25;
if((Tm&0x8000)==0x800)
{ //liczba ujena
minus=1;
Tm=~Tm;
Tm=Tm+1;
}
else minus=0;
Str[0]=0;
while(Tm>99){ Tm=Tm-100; Str[0]++; } //wyliczenie czeci calokwitej
Tb01=(char)Tm; //reszta to cyfra po przecinku
Tb01=Tb01/10; //tylko jedno miejsce po przecinku
jeli macie jaki lepszy kod to będę wdzięczny.
Zerknąłem tylko w pośpiechu. Jeśli jednak skopiowałeś kod bezpośrednio, to:
Ogólnie aby uniknąć takich problemów polecam:
Albo jeszcze lepiej... nie pozostawiająć jakichkolwiek wątpliwości:
Też będzie działać prawidłowo
Jaki to kompilator nie obsługuje signed char? Jeśli to gcc, polecam przyjrzenie się nagłówkowi inttypes.h
Kod: Zaznacz cały
if((Tm&0x8000)==0x800) <- może sam widzisz już błąd?
Kod: Zaznacz cały
if(Tm&0x8000)
Kod: Zaznacz cały
if(Tm<0)
Jaki to kompilator nie obsługuje signed char? Jeśli to gcc, polecam przyjrzenie się nagłówkowi inttypes.h