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.
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
chodzi o wartości binarne, czyli float 2.0 nie bedzie reprezentowany tak samo jak int bo bedzie mial inne pola chociażby mantysy
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
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 );
Najprościej:
http://en.cppreference.com/w/cpp/language/union
to jest druga część tego zadania 1) przy pomocy wskaźników, 2) przy pomocy uni :D
W obu przypadkach to jest UB i nie powinno się tak robić.
Jedyne co możesz bezpiecznie zrobić to rzutować wskaźnik do char*.
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
.
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;
}
float f = 2.0f;
int i = *(int*)&f;
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.