Konwersja "float to binary"

Odpowiedz Nowy wątek
2013-11-03 03:14

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Na wstępie chciałem wszystkich miło powitać, dzień dobry ;)

Przywiódł mnie na forum pewien problem, którego jak na razie nie mogę rozwiązać.
Otóż mam za zadanie napisać program w C, który zamieni liczbę zmiennoprzecinkową (float) na binarną oraz podać znak, mantysę i cechę.

Nie mam problemu przy zamianie np. int, fragment mojego kodu:

void konwersja(int liczba, int podstawa)
{
    if (liczba==0) return;
    int wynik = liczba%podstawa;
    liczba /= podstawa;
    konwersja(liczba, podstawa); 
    if (wynik < 10) 
        printf("%i ",wynik);   
    else 
    {
        char litera = wynik + 55;
        printf("%c",litera);
    }

}

Lecz problem pojawia się, gdy w grę zaczynają wchodzić liczby float.
Prosiłbym o jakąś wskazówkę jak się za to zabrać ;)

Pozdrawiam
f.

edytowany 1x, ostatnio: formalny, 2013-11-03 03:14

Pozostało 580 znaków

2013-11-03 09:38

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

1

http://pl.wikipedia.org/wiki/IEEE_754
Najprościej - przepisz do unsigned za pomocą memcpy() lub użyj union.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-11-03 13:53

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Dziekuje za odpowiedz. Czytalem o tej reprezentacji, tak samo jak interesujace bylo np. to : http://kipirvine.com/asm/workbook/floating_tut.htm

Szczerze mowiac nie chcialbym tego robic w najprostszy sposob, ale bardziej matematycznie.
Czy duzym bledem byloby gdybym zrobil rzutowanie float na int aby obcielo czes dziesietna i zamienic to na binarne? Po kropce binarnej znalazla by sie czesc ulamkowa po konwersji wg. schematu:

Algorytm przedstawiania ułamka u w binarnym systemie pozycyjnym.
Założenie: 0< u <1.
Napisz 0.. Kolejne cyfry rozwinięcia binarnego będziemy generować w następujący sposób:
Dopóki otrzymujesz nienapotkane wcześniej wartości u wykonuj
1. Pomnóż u przez 2
2. Jeżeli otrzymana wartość jest mniejsza od 1, to dopisz cyfrę 0
3. Jeżeli otrzymana wartość jest równa co najmniej 1, dopisz cyfrę  1 i odejmij od 
   wyniku 1. Z chwilą, gdy powtórzy się wartość u, zakończ procedurę; wypisany ciąg 
   jest okresowy, a jego okresem jest ciąg bitów między powtórzeniami.   

Oczywiscie sama czesc ulamkowo zdobylbym poprzez odejmowanie pierwszego float po rzutowaniu od float wejsciowego.

Nie wiem tylko jak potem zabrac sie za mantyse, ceche bo znak jest oczywisty.
Czy to rozumowanie jest poprawne?

edytowany 1x, ostatnio: formalny, 2013-11-03 13:55

Pozostało 580 znaków

2013-11-03 14:01

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

1

float x=3E30; - do żadnego int'a się nie zmieści.

float x=3E30;
unsigned X;
memcpy(&X,&x,sizeof(x));
unsigned mantysa=X&((1<<23)-1);
unsigned wykładnik=(X>>23)&((1<<8)-1);
unsigned sign=X>>31;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-11-03 14:11

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0
_13th_Dragon napisał(a):

float x=3E30; - do żadnego int'a się nie zmieści.

float x=3E30;
unsigned X;
memcpy(&X,&x,sizeof(x));
unsigned mantysa=X&((1<<23)-1);
unsigned wykładnik=(X>>23)&((1<<8)-1);
unsigned sign=X>>31;

Tak rozumiem, sugerujesz, że nie ma co tracić pamięci i czasu jeżeli istnieje lepszy sposób? :)
Ok mam rozumieć, że dla double będzie to standard "IEE-754 double" czyli dla tego kodu zamiana 8 -> 11; 23->52; 31->63 ?

Moglbym prosic o podrzucenie jakiegos ciekawego artykulu jesli chodzi o przechowywanie pamieci, przesuniecia bitowe i operacje logiczne w c?

edytowany 3x, ostatnio: formalny, 2013-11-03 14:47

Pozostało 580 znaków

2013-11-03 14:46

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

1
formalny napisał(a):

Moglbym prosic o podrzucenie jakiegos ciekawego artykulu jesli chodzi o przechowywanie pamieci, przesuniecia bitowe i operacje logiczne w c?

& - oraz tak jak w normalnej logice lecz dla każdego bitu osobno
| - lub tak jak w normalnej logice lecz dla każdego bitu osobno
^ - "czy rózne" dla każdego bitu osobno
przesunięcie << dopisanie odpowiedniej liczby zer z prawej strony w kodzie bitowym
przesunięcie >> usunięcie odpowiedniej liczby cyfr z prawej strony w kodzie bitowym

ot cała filozofia.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-11-03 14:48

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Ok dziekuje bardzo za pomoc.

Jeszcze glupie pytanie: Czy unsigned to skrot do unsigned int? Jak wyswietlic/wydrukowac poprawnie zawartosc z pamieci patrzac na powyzszy kod?
Oczywiscie wiem, ze memcpy potrzebuje biblioteki string.h

edytowany 2x, ostatnio: formalny, 2013-11-03 14:49

Pozostało 580 znaków

2013-11-03 14:56

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

0

Ad.1. tak.
Ad.2. printf("%f",x);


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-11-03 15:03

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Tak myślałem i tak zrobiłem. Ale przy próbie np. wydrukowania mantysy są same 0.

Pozostało 580 znaków

2013-11-03 15:08

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

0

Przeczytaj ten artykuł i dowiedz się jak ta mantysa jest kodowana


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-11-03 15:22

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Wiem, że znak jest zapisywany za pomocą 1 bitu, cecha 8 bitów, a mantysa 23 bitów z pominięciem wiodącego niezerowego.
Wszystkie bity mogą być zerami, ale np. w kodzie z nadmiarem albo jak wyjdziemy poza zakres.

Dla przykładu chcę wziąć prostą liczbę np. 1+1/2 czyli 1.5 w systemie dziesiętnym.
Powinno wyjść tak:

postać binarna: 00000000 00000000 11000000 00111111
mantysa: 10000000000000000000000
cecha: 01111111
znak: 0

a output dostaje:
4194304.000000
4194304.000000
4194304.000000

Podejrzewam, że rozwiązanie jest banalne, ale zawsze wszystko robiłem na intach i pierwszy raz szczerze mówiąc mam doczynienia z memcpy.

Pozostało 580 znaków

Odpowiedz

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