Konwersja z uint8_t na float.

0

Cześć.
Dostaję ramkę danych za pomocą pewnego interfejsu i mam ją zapisana w tablicy typu uint8_t. Załóżmy że pierwsze 4 elementy opisują pierwszą liczbę typu float a kolejne 4 drugą liczbę typu float.
Zazwyczaj robiłem to tak że tworzyłem unię
typedef union
{
uint8_t u8_val[4];
float f_val;
}union_u8_f;

Za pomocą takiej unii konwertowałem 4 elementy typu uint8_t na float. Niestety pewien standard tego zabrania. W jaki sposób dokonać takiej konwersji z czterech liczb typu uint8_t na jednego float'a i na odwrót.

0
  • Jaki standard tego zabrania?
  • W C++ masz reinterpret_cast (o ile nazwy nie pomieszałem), a w C można coś podobnego rzutowaniem chyba zrobić.
  • Jak nie, to na piechotę -- przeglądać pamięć po bajcie (za pomocą char *) i przenosić między danymi...
0

Język C++ nie wchodzi w grę.
Standard wewnętrzny oparty na standardzie MISRA C 2004 zabrania użycia unii. Dlaczego? Nie mam pojęcia.

0

C

float myfloat = *( (float*)&uint8_sequence );

C++

float myfloat = *( reinterpret_cast< float* >( &uint8_sequence ) );
0

Dzięki,
Szerze mówiąc to nie wpadłem na taki sposobu konwersji :). Działa poprawnie, zobaczymy jeszcze czy przejdzie Code Review.

1

W C++ takie "castowanie" za pomocą unii to UB.

5

Użyj memcpy.

void to_uint8_t(float f, uint8_t* arr)
{
    memcpy(arr, &f, sizeof(f));
}

void to_float(uint8_t const* arr, float* f)
{
    memcpy(f, arr, sizeof(*f));
}

I zanim zacznie się jojczenie o "wywołania funkcji": https://godbolt.org/g/qMgxu3

1
pingwindyktator napisał(a):

W C++ takie "castowanie" za pomocą unii to UB.

A kompilatory obsługują to jako rozszerzenie.
I słusznie, bo standard jest w tej kwestii nadmiernie restrykcyjny, nie dając właściwie żadnego rozwiązania.
memcpy to nie rozwiązanie, bo jest powolne - niepotrzebnie kopiuje pamięć.

Liczenie na optymalizację kiedy kod wyraźnie mówi coś innego to też nie rozwiązanie.

0

Sposób zaproponowany przez użytkowników kQ i undefined reference przeszedł przez Code Review.
Ciekawy tylko jestem co jest złego w zastosowaniu unii w celu rzutowania?

0

Co nie zmienia faktu, że tak jak napisał @kq jest to UB i trzeba mieć oko na te miejsca w kodzie, gdzie jest to użyte.

1 użytkowników online, w tym zalogowanych: 0, gości: 1