Forum Delphi.cz

Delphi => Obecné => Téma založeno: PepaS 12-02-2020, 06:54:03

Název: Delphi převod 4 byte na float signed. Endian?
Přispěvatel: PepaS 12-02-2020, 06:54:03
Dobrý den. Mám převádět hodnotu načtenou ve čtyřech bytech  a potřebuji to převést na číslo s plovoucí desetinnou čárkou se znaménkem. Nevím jak na to. Mohl by mi prosím někdo poradit?

Příklad: Mám ve čtyřech bytech uloženo
var
   b1,b2,b3,b4:byte;
   xx:real;
begin
   b1:=$51;  b2:=$9a;  b3:=$c6;  b4:=$43;
   xx:= funkce(b1,b2,b3,b4);                        //xx= - 12 500.4   - záporná hodnota kterou bych měl dostat
                                                                  // 51 9a 46 43 odpovídá kladná výsledná hodnota xx= 12 500.4

Příklad správných výsledků
51 9a c6 43 = -12 500.4  = 0101 0001 1001 1010 1100 0110 0100 0011 
51 9a 46 43 = 12 500.4  =  0101 0001 1001 1010 0100 0110 0100 0011 

Pravděpodobně jde o nějaký endian přepočet, kdy jeden bit udává znaménko a nějakým přepočtem dostanu pak výsledné číslo. Hledal jsem zde, v publikovaných příspěvcích, ale nenašel. Věděl by někdo prosím, jak napsat funkci pro převod čtyř bytů na float? Pepa
Název: Re:Delphi převod 4 byte na float signed. Endian?
Přispěvatel: vandrovnik 12-02-2020, 08:57:23
Ahoj, něco jako:

Kód: Delphi [Vybrat]
  1.  type tPrevod=packed record
  2.   case integer of
  3.    0: (s: single);
  4.    1: (b2, b1, b4, b3: byte);
  5.  end;
  6.  var Prevod: tPrevod;
  7.  begin
  8.  Prevod.b1:=$51;
  9.  Prevod.b2:=$9a;
  10.  Prevod.b3:=$c6;
  11.  Prevod.b4:=$43;
  12.  // v Prevod.s je nyni vysledek

Ale jestli to je nějaký domácí úkol, hádám, že toto řešení nebude preferováno :-)
Název: Re:Delphi převod 4 byte na float signed. Endian?
Přispěvatel: PepaS 12-02-2020, 13:06:33
Ahoj a díky za řešení. Funguje! Překvapilo mne svou jednoduchostí zápisu, ale pro mne je to ‚vyšší dívčí‘, které nerozumím. Použití recordu.
Type Tprevod = packed record
  case integer of
   0:(s:single);
   1:(b2, b1, b4, b3: byte);
  end;

Packed je nějaká komprese recordu?
Single je desetinné 4 bytové číslo se znaménkem, OK
Case integer of   … nějaké překrývání proměnných???? Jak to funguje?  Variantní typ závislý na vstupu? Hodnota ‘Integer‘ se bere odkud? Vyhodnotí se vstup podle toho co přijde do b1-b4?

Typ record používám zatím jen takhle
type  Tosoba = record
    Jmeno: string;
    prijmeni: string;
    cisloBoty: integer;
  end;

Název: Re:Delphi převod 4 byte na float signed. Endian?
Přispěvatel: vandrovnik 12-02-2020, 13:16:56
Na http://docwiki.embarcadero.com/RADStudio/Rio/en/Structured_Types_(Delphi)#Variant_Parts_in_Records (http://docwiki.embarcadero.com/RADStudio/Rio/en/Structured_Types_(Delphi)#Variant_Parts_in_Records) je nějaké povídání.

Packed tam píšu, abych měl jistotu, že jednotlivá pole budou v paměti "hned za sebou" (aby je kompilátor kvůli nějakým optimalizacím neproložil prázdným místem). V téhle ukázce by sizeof(Prevod) mělo vrátit 4.

Ten zápis je divný :-), skutečná hodnota toho integer není nikde, je to prostě jen forma zápisu; každá větev v tom "case" je v paměti na stejném místě jako ostatní větve, tím pádem když změníš "s", má to vliv na b1-b4, zrovna tak opačně změnou b1-b4 dojde ke změně "s".
Název: Re:Delphi převod 4 byte na float signed. Endian?
Přispěvatel: JaroB 13-02-2020, 14:51:28
Je to prostě jenom "jiný" pohled na data a bonus plus je možnost používat v records i property a metody :)