logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] Jak poprawnie skalować liczby ujemne w C przy użyciu akcelerometru?

cobi_69 21 Lip 2011 18:52 1309 8
REKLAMA
  • #1 9743206
    cobi_69
    Poziom 21  
    Posty: 620
    Ocena: 11
    Napisałem sobie programik do obsługi akcelerometru w C. Wszystko działa fajnie, ale chciałem jeszcze wynik przeskalować mnożąc go przez 1.5 i wtedy się pojawiają problemy. Chodzi o to że normalnie zakres napięć to -60:+60, ale ja chciałem to przemnożyć żeby zakres był -90:+90 (chodzi o stopnie), ale gdy zmienię linijkę:
    wynik_x = pomiar_x - 512;

    na:
    wynik_x = (pomiar_x - 512) * 1.5;

    to gdy dojdzie do liczb ujemnych wyskakują liczy np. 65345 itp
    Domyślam się że chodzi o deklarację typu zmiennych, ale o co dokładnie?

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • REKLAMA
  • #3 9743469
    cobi_69
    Poziom 21  
    Posty: 620
    Ocena: 11
    też tak myślałem, ale w takim razie czemu na dodatnich działa?

    Poza tym jest w zwykłym C jakaś funkcja zaokrąglająca? Bo w C++ wiem.
  • REKLAMA
  • #4 9743571
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Mnie bardziej dziwi, że kompilator w ogóle dopuścił taką składnię.

    Math.round nie ma?

    Alternatywnie możesz pomnożyć przez 15, a wynik podzielić przez 10 (dzielenie całkowite). Co prawda da różnice względem funkcji zaokrąglenia, ale w ogóle nie użyjesz FPU.
  • REKLAMA
  • #5 9743613
    krru
    Poziom 33  
    Posty: 1819
    Pomógł: 230
    Ocena: 214
    cobi_69 napisał:
    też tak myślałem, ale w takim razie czemu na dodatnich działa?


    Bo masz unsigned.

    cobi_69 napisał:
    Poza tym jest w zwykłym C jakaś funkcja zaokrąglająca? Bo w C++ wiem.


    Samo przypisanie do int-a obcina część ułamkową. Jak dodasz 0.5 wyjdzie zaokrąglenie.
  • #6 9743649
    cobi_69
    Poziom 21  
    Posty: 620
    Ocena: 11
    unsigned jest "pomiar_x" a to zawsze jest dodatnie, dopiero po odjęciu 512 może być ujemna a to już jest "wynik_x" który jest signed.

    a wynik jest akurat int a mimo to go nie obcina, chyba że to nie o to chodzi bo:
    wynik_x = ((pomiar_x - 512) * 15)/10;

    też nie pomogło, dalej to samo
  • #7 9744500
    krru
    Poziom 33  
    Posty: 1819
    Pomógł: 230
    Ocena: 214
    Ale wykorzystywany operator zależy od argumentów a nie oczekiwanego wyniku. Unsigned 'przebija' signed i jeśli jeden z argumentów jest unsigned cała operacja traktowana jest jako unsigned.
  • #8 9744843
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Przecież Tobie w ostatnim temacie napisałem wynik=(((int)pomiar-512)...
    Musisz zamienić pomiar na liczbę ze znakiem.
    Swoją drogą jeżeli akcelerometr zwraca Tobie liczbę mniejszą niż 16bitowa to możesz zrobić spokojnie int pomiar, bo czy tak bit znaku nigdy nie zostanie nadpisany przez dane z akcelerometru. Nie jest to piękne rozwiązanie, ale działać będzie.
  • #9 9746260
    cobi_69
    Poziom 21  
    Posty: 620
    Ocena: 11
    Rzeczywiście wystarczyło zmienić pomiar_x na signed, zaskoczyło mnie to rozumowanie ale jest prawidłowe, znów się czegoś nauczyłem

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik napotkał problem przy skalowaniu wartości z akcelerometru w języku C, gdy próbował pomnożyć wynik przez 1.5, co prowadziło do nieprawidłowych wartości ujemnych. Dyskusja skupiła się na typach zmiennych, gdzie pomiar_x był typu unsigned int, co powodowało, że operacje na nim były traktowane jako unsigned, a wynik_x, będący signed int, nie mógł poprawnie obsłużyć wartości ujemnych. Uczestnicy zasugerowali konwersję pomiar_x na signed int oraz alternatywne metody zaokrąglania, takie jak mnożenie przez 15 i dzielenie przez 10. Ostatecznie, zmiana typu pomiar_x na signed rozwiązała problem.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA