Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Konwersja z utratą precyzji

Ostatnio zmodyfikowano 2019-04-29 02:25
Autor Wiadomość
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
C/C++
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
C/C++
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 :
C/C++
int8_t conv( const long long & in )
{
    int8_t out;
    if( in > 127 || in <( - 128 ) )
    {
        throw std::overflow_error( "overflow" );
    }
    else
    {
        out = in & 0x7F; //7
       
        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.
P-174541
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 2n, 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.
P-174542
« 1 »
  Strona 1 z 1