Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Konwersja double -> sfixed (C, C++)

mariusz102102 26 Kwi 2008 14:25 1339 10
  • #1 26 Kwi 2008 14:25
    mariusz102102
    Poziom 11  

    Witam,

    Potrzebuje skonwertowac 64 bitowego double (IEEE 754),
    do postaci stalo przecinkowej (FixedPoint(n,m))
    gdzie n i m
    n - liczba bitow przed przecinkiem
    m - liczba bitow po przecinku
    FixedPoint(2,4) = 11,1111

    np wartosc 0.5 (polowa dziesietnie):
    dla (IEEE 754) = 3fe0000000000000 (hex)
    dla FixedPoint(2,4) = 00,1000 (bin)

    Dokladnie potrzebuje skonwertowac tablice double[] na ciagly obszar pamieci zawierajucy liczby typu (FixedPoint(n,m))
    czyli np tablice double 0,5;1,5,0,5.... na
    001000 011000 001000 ..............................

    Tak przetworzone dane maja zostac przeslane do FPGA. Dlatego to pytanie umiescilem :)

    Pozdrawiam
    Mariusz

    Przeniosłem z Układy programowalne. [c_p]

  • #2 26 Kwi 2008 15:24
    UDMA
    Poziom 16  

    Zapomniałeś zadać pytanie.

  • #3 26 Kwi 2008 16:43
    mariusz102102
    Poziom 11  

    Jak efektywnie przy pomocy C++ skonwerotwac tablice liczb double do tablicy liczb FixedPoint?

    Bardzo prosze o przeslanie prrzykladow, linkow.

    Teraz jest jawne pytanie i jawna prosba ;)
    Pozdrawiam
    Mariusz

  • #4 26 Kwi 2008 16:49
    Freddie Chopin
    Specjalista - Mikrokontrolery

    mariusz102102 napisał:
    efektywnie
    Cytat:
    C++


    te dwa slowa sa ze soba sprzeczne [;

    niemniej jednak jesli robisz to na PCcie (robisz to na PC?) to wcale nie musi byc efektywnie [;

    0x41 0x56 0x45!!

  • #5 26 Kwi 2008 17:33
    mariusz102102
    Poziom 11  

    Cytat:
    te dwa slowa sa ze soba sprzeczne [;

    niemniej jednak jesli robisz to na PCcie (robisz to na PC?) to wcale nie musi byc efektywnie [;

    :) uff
    Szczrze mowiac to nie wiem o co chodzi w twojej odpowiedzi

    Moze chcesz wiecej informacji .... to prosze:
    Uzywam:
    - "nieefektywnego" PC
    - z "nieefektywnym WinXP
    (z "nieefektywnym" PC i WinXP itd sie nie zgadzam wszystko zalezy od zastosowan, mozna do pralki wlozyc 10 RASC-ow, 20 FPGA, ale po co ???)

    Oraz:
    - Virtex4fx (100 , 60)
    - komunikacja PC-DMA-PCIe 8 - lini (teoretyczny transfer 2GB).

    Projekt.
    Dane pobieram z komputera PC w postaci double (int itp.):
    - daane nalezy skonwertowac do postaci stalo przecinkowej (PC)
    - przeslac do CoProcesora (PCIe-DMA)
    - przetworzyc (np b. duzy filtr) (Virtex4Fx)
    - odebrac przetworzone dane, (PCIe-DMA)
    - skonwertowac do double (PC)
    - wyswietlic wynik na PC (PC)

    Problem:
    Dane chce przetwarzac "w czasie rzeczywistym" (np dzwiek z mikrofonu) .
    Dlatego potrzebuje efektywnie zaimplementowac konwersje danych

    Pozdrawiam
    Mariusz

  • #6 26 Kwi 2008 17:37
    Freddie Chopin
    Specjalista - Mikrokontrolery

    dzwiek z mikrofonu to probki tak rzadkie ze komp ci 'umrze z nudow' miedzy nimi [; tak wiec raczej nie masz sie co przejmowac kwestia wydajnosci (chyba ze masz 386, ale one nie mialy raczej PCIe [; )

    konwersja tego 'na piechote' jest dosyc prosta - bierzesz takiego doubla i rzutujesz go sobie na inta - masz czesc calkowita. odejmujesz ta czesc calkowita od tego doubla i zostaje ci czysta czesc ulamkowa. potem troche liczenia, pare rotacji, jeden OR i gotowe.

    0x41 0x56 0x45!!

    0x41 0x56 0x45!!

  • #7 26 Kwi 2008 17:46
    Dr_DEAD
    Poziom 28  

    Freddie Chopin trochę to skomplikował... Bierzesz Floata mnożysz go razy 16 i rzutujesz na inta. No i proszę gotowy wynik (chyba że coś źle rozumuje).
    0,5 * 16 = 8 = (1000)B - czyli tyle ile chciałeś.

  • #8 26 Kwi 2008 18:18
    Freddie Chopin
    Specjalista - Mikrokontrolery

    tu chyba chodzilo o funkcje ktora zrobi to dla dowolnego podanego w wywolaniu formatu. no chyba ze nie, to faktycznie nie ma sie co rozpieszczac

    0x41 0x56 0x45!!

  • #9 26 Kwi 2008 19:00
    Dr_DEAD
    Poziom 28  

    Freddie Chopin napisał:
    tu chyba chodzilo o funkcje ktora zrobi to dla dowolnego podanego w wywolaniu formatu. ...

    AAAAA no to w takim razie:
    Float * 2^m a następnie zrzutowanie do inta.
    gdzie:
    m - liczba miejsc po przecinku.

  • #10 28 Kwi 2008 11:48
    mariusz102102
    Poziom 11  

    Witam,

    Dziekuje za odpowiedz.


    Konwersja do double na unsigned long (przeskalowanego) to jest ta latwiejsz czesc.
    Do przemnozenie przez 2^m dodalem jeszcze zaokraglanie i sprawdzanie zakresu

    Code:
    double*2^m
    
    zokraglenie (+-0.5 )
    rzutowanie na long
    rzutowanie na unsigned long
    sprawdzenie czy nie zostal przekroczony zakres (jesli >max  011111, jesli <min 10000)

    Problem mam z upakowaniem tego w "pamieci"
    np.: FixedPoint(3,4)
    000,1000 ; 000,1000

    Czyli teraz np.: 100 liczb FixedPoint(3,4)-7bitowych musi zajmowac ciagly obszar pamieci 87,5 bajta (700 bitow). Kombinuje cos z std::bitset (a w zasadzie to z boost::dynamic_bitset) i std::vector<bool>. I cos mi to bardzo skomplikowane wychodzi.

    Jakies pomysly jak to mozna efektywnie zrobic?

    Pozdrawiam
    Mariusz

  • #11 28 Kwi 2008 12:58
    Dżyszla
    Poziom 42  

    Maski bitowe bedące wskaźnikami, a więc (mogę PAscalem? łatwiej mi się myśli):

    Code:

    const
       LLength=64; //podajesz najstarszy znaczący bit przepisywanej liczby
    var
       InputMask, OutputMask: byte;
       OutputPtr: Longint;
    begin
       InputMask:=LLength;
       OutputMask:=128; //10000000b
       OutputPtr:=0;
       
       repeat
          OutTable[OutputPtr]:=0;
          if (licza and InputMask) > 0 then OutTable[OutputPtr]:=OutTable[OutputPtr] or OutputMask;
          OutputMask:=OutPutMask shr 1;
          if OutPutMask=0 then begin
                 OutputMask:=128;
                 Inc(OutputPtr);
          end;
          InputMask:=InputMask shr 1;
       until InputMask=0;

    Oczywiście przykłąd zapisuje jedną liczbę bajtową. Można ładnie opakować w funkcje, pozostawiając jako globalne wskaźnii na wyjście (albo jako stałe statyczne - w C chyba można tak zdaje się:D).

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME