wartości binarne z floata do integera

0

Witam, mam za zadanie zamienić dane binarne reprezentujacę liczbę float na typ całkowito-liczbowy i za bardzo nie wiem jak się za to zabrać. Pamiętam, że prowadzący wspominał coś o wskaźnikach i adresach. Z góry dziękuję za pomoc. Program piszę w języku C.

0

Na moje to będzie

float f = 2.0;
int a;
a = f; 

Ale to chyba nie o to chodzi. Sprecyzuj, podaj jakiś przykład bo nie wiem jak inni, ale ja chyba nie rozumiem

0

chodzi o wartości binarne, czyli float 2.0 nie bedzie reprezentowany tak samo jak int bo bedzie mial inne pola chociażby mantysy

0

CHodzi o to że powiedzmy kod 10101010101010101010101010101010 jest inna liczbą którą reprezentuje float i inną ktora reprezentuje int. Chodzi o to zeby pokazać właśnie te dwie rozne wartosci na wskaznikach

0

No tak. To chodzi Ci, że dostaniesz mantyse i ceche i zmieniasz to na liczbę?
Czy masz wskaźnik do float i z niego wyłuskujesz mantysę i cechę i wtedy zamieniasz to na liczbę?

Chodzi o to zeby pokazać właśnie te dwie rozne wartosci na wskaznikach tego nie rozumiem

Chodzi o coś takiego?

void *ptr = coś;
printf( "float: %f\nint: %d", *ptr, *ptr );
 
0

to jest druga część tego zadania 1) przy pomocy wskaźników, 2) przy pomocy uni :D

0

W obu przypadkach to jest UB i nie powinno się tak robić.
Jedyne co możesz bezpiecznie zrobić to rzutować wskaźnik do char*.

1

Przy pomocy wskaźników - undefined behavior w C i C++. Można to "obejść" wyłączając strict aliasing w kompilatorze ale to nie jest dobre rozwiązanie. (W GCC -fno-strict-aliasing)
Przy pomocy unii - undefined behavior w C++, z pewnością well defined w >=C99 jeżeli typy mają takie same rozmiary. Ponadto np. GCC gwarantuje, że w C++ to też będzie działać.

Bezproblemową metodą działająca zawsze i wszędzie powinno być memcpy.

0

Rozpisując się:

O typie float nie można nawet powiedzieć, że jest zmiennoprzecinkowy. Nie ma takiej gwarancji. Niektóre kompilatory gwarantują, że jest to 32-bitowa liczba zmiennoprzecinkowa (IEEE-754). Przy pomocy unii można zrobić to w ten sposób:

#include <cinttypes>
#include <iostream>

union intFloat {
    uint32_t Int;
    float Float;
    intFloat (uint32_t i) : Int(i) { }
    intFloat (float f) : Float(f) { }
};

int main () {
    
    uint32_t intV = 1;
    intFloat iVU = intFloat(intV);

    float floatV = 1.0;
    intFloat fVU = intFloat(floatV);

    std::cout << iVU.Int
              << '\n'
              << iVU.Float
              << '\n'
              << fVU.Int
              << '\n'
              << fVU.Float
              << std::endl;
}

Lub przez memcpy:

#include <cinttypes>
#include <iostream>
#include <cstring>

#ifndef __STDC_IEC_559__
#error "Size of float might not equal 32bit"
#endif

int main () {

    uint32_t intV = 1;
    float floatV;

    memcpy (&floatV, &intV, sizeof(int));

    std::cout << intV
              << '\n'
              << floatV
              << std::endl;
}
1
float f = 2.0f;
int i = *(int*)&f;

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