Konwersja z utratą precyzji
Ostatnio zmodyfikowano 2019-04-29 02:25
rafallauterbach Temat założony przez niniejszego użytkownika |
Konwersja z utratą precyzji » 2019-04-28 23:50:01 Chciałbym przekonwertować liczbę z long long to uint8_t . dla long long ii = 0x12345678; uint8_t a = ii;
std::cout <<( int ) a << std::endl;
otrzymuję 120
Wydaje mi się, że konwersja ta "ucina" po prostu najstarsze bity i też nie wiem, czy to jest "undefined behaviour", czy wszystko jest w porządku jak tak przypisuję zmienną? Chciałbym otrzymywać jakiś bład, gdy liczba nie jest "odpowiednia" do konwersji. No i mam też problem z konwertowaniem liczb ujemnych.. dla long long ii = - 0x123456FF; int8_t a = ii;
std::cout <<( int ) a << std::endl;
otrzymuję 1
Więc chyba dwa razy zmienia mi się znak (raz z powodu minusa przed liczbą z ii i drugi raz, gdy po odcięciu bitów pierwszy z 8 pozostałych służy za -128. Akceptuję i aprobuję to, żeby brać pierwszy i ostatnie bity, ale wolałbym, żeby konwersja brała pod uwagę pierwszy i 7 ostatnich (a nie 8 ostatnich) bitów. Może powinienem użyć konkretnego rodzaju x_cast, czy też może istnieją jakieś funkcje, które zachowują się dokładnie tak jakbym tego oczekiwał? (Używając static_cast jak sugerowało mi kilka forów nie robi żadnej różnicy - działa to dokładnie tak samo jak przypisanie.) Taka funkcja : int8_t conv( const long long & in ) { int8_t out; if( in > 127 || in <( - 128 ) ) { throw std::overflow_error( "overflow" ); } else { out = in & 0x7F; if( in < 0 ) { out -= 128; } } return out; }
Działa raczej tak jak bym tego oczekiwał. Ale pewnie nie jest tak optymalna jak się da, no i pewnie jest jakaś już istniejąca - lepsza implementacja. |
|
pekfos |
» 2019-04-29 02:25:39 Konwersja zawężająca liczby ze znakiem, w przypadku gdy wartość jest niereprezentowalna w typie docelowym, ma zachowanie zależne od implementacji. Od C++20 wynik będzie modulo 2 n, jak dla liczb bez znaku. Ale pewnie nie jest tak optymalna jak się da |
Jeśli wartość jest w zakresie, nie musisz nic robić. A jeśli nie jest, to idea takiej funkcji prawdopodobnie nie ma sensu pod względem wydajności. |
|
« 1 » |