Převod 32 Int na float – Assembler – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Převod 32 Int na float – Assembler – Fórum – Programujte.comPřevod 32 Int na float – Assembler – Fórum – Programujte.com

 

Jakub Kohout
~ Anonymní uživatel
4 příspěvky
14. 5. 2014   #1
-
0
-

Dobrý den,

snažím se napsat kód pro převod 32 bitového int čísla na float. Jediné co jsem byl schopen vypotit je tohle, ale je tam nekde chyba.

 

#include <stdio.h>

float itof (int i)
{
    float flt = 0.0;

    _asm
    {
        mov eax, i
        bt eax, 31
        jnc plus

        rcr [flt], 1
        neg eax

        plus:

        mov edx, 0x7F       // Bias

        bsr ebx, eax

        mov ecx, 23
        cmp ebx, ecx
        jbe fit

        // too big:
        sub bl, cl
        mov cl, bl
        shr eax, cl
        setc cl             // to round or not to round
        add eax, ecx
        add edx, ebx
        mov cl, 23

        fit:
        bsr ebx, eax
        btr eax, ebx
        sub cl, bl
        shl eax, cl
        or [flt], eax

        add ebx, edx
        shl ebx, 23
        or [flt], ebx
    }

    return flt;
}

int main ( void )
{
    float flt;
    int i;

    i = 12345678;
//  i = -0x8888888;     // different results, both are right

    flt = (float)i;
    printf("%i  %f\n",i,flt);

    flt = itof (i);
    printf("%i  %f\n",i,flt);

    return 0;
}

Nevíte někdo co je tam špatně?

Předem děkuji za všechny reakce.
 

Nahlásit jako SPAM
IP: 147.228.209.–
pee-jay_cz0
Návštěvník
15. 5. 2014   #2
-
0
-

   

fild    MyInteger       ; Fpu Integer LoaD
fst     MyFloat         ; Fpu STore

tohle se konvertuje hardwarově.

leda by to někdo studoval, aby si třeba napsal rozšíření; delší exponent, více číslic = větší přesnost.

Nahlásit jako SPAM
IP: 213.129.136.–
Jakub Kohout
~ Anonymní uživatel
4 příspěvky
15. 5. 2014   #3
-
0
-

#2 pee-jay_cz
takže to se těma dvouma řádkama dá nahradit celej ten můj kód? Promiň, že se ptám takhle blbě, ale jsem v assembleru fakt ztracenej.

Díky za tvůj čas.

Nahlásit jako SPAM
IP: 85.70.141.–
pee-jay_cz0
Návštěvník
16. 5. 2014   #4
-
0
-

tohle taky funguje... :-)

'--------------------------
' VB6 Code
' Int je zaokrouhlit dolu = useknout desetiny
'--------------------------
e = Int(Log(MyInteger) / Log(2))    ' dve na kolikatou je MyInteger?
f = MyInteger - 2 ^ e               ' zbytek
fE = (127 + e) * 2 ^ 23             ' plus 127 a shift left 23 = bity (30 az 23)
fM = f * (2 ^ (23 - e))             ' posun na bity 22 az 0
MyFloat = fE + fM
'==========================
MyFloat = (127 + Int(Log(MyInteger) / Log(2))) * 2 ^ 23 + (MyInteger - 2 ^ (Int(Log(MyInteger) / Log(2)))) * (2 ^ (23 - e))
'==========================
Nahlásit jako SPAM
IP: 213.129.136.–
pee-jay_cz0
Návštěvník
16. 5. 2014   #5
-
0
-

Bity v obou číslech jsou hodně podobný. Stačí najít pozici nejvyššího nenulového bitu Integeru, ten zbytek posunout na správnou pozici "Fractu", místo té jedničky zapsat do bitů 30 až 22 její původní pozici +127 a do nejvyššího bitu (31) případně znaménko.

e = Int(Log(MyInteger) / Log(2)) je pozice nejvyššího nenulového bitu...

Můj algo:

1. otočit bajty DWORDu 1,2,3,4 -> 4,3,2,1
2. posunout bity doleva o 32-e, ať se ztratí ta nejvyšší jednička
3. posunout bity doprava o 8 = vytvořit místo pro exponent
4. do těch osmi bitů zleva zapsat exponent (e+127)
5. posunout bity doprava o 1 = vytvořit místo pro znaménko
6. zapsat znaménko, pokud byl ten DWORD záporný
7. otočit bajty DWORDu 4,3,2,1 -> 1,2,3,4

0. Pokud je to číslo záporné musí se negovat a pamatovat si znaménko, jinak nevim.

Proč ti to nefunguje nevím, páč assembler teprve začínám rozlišovat :-)

Nahlásit jako SPAM
IP: 213.129.136.–
pee-jay_cz0
Návštěvník
16. 5. 2014   #6
-
0
-

#5 pee-jay_cz
Exponent není v bitech 30 až 22, ale 30 až 23. Je jich osm.

Nahlásit jako SPAM
IP: 213.129.136.–
pee-jay_cz0
Návštěvník
16. 5. 2014   #7
-
0
-

#4 pee-jay_cz

ver 2.

If MyInteger = 0 Then
        MyFloat = 0
    
    Else
        
        s = Sgn(MyInteger) - 1
        e = Int(Log(Abs(MyInteger)) / Log(2))
        f = Abs(MyInteger) - 2 ^ e
        fS = s ^ 31
        fE = (127 + e) * 2 ^ 23
        fF = f * (2 ^ (23 - e))
        MyFloat = fS + fE + fF
        
        'one-liner
        MyFloat = (Sgn(MyInteger) - 1) ^ 31 + (127 + Int(Log(Abs(MyInteger)) / Log(2))) * 2 ^ 23 + (Abs(MyInteger) - 2 ^ (Int(Log(Abs(MyInteger)) / Log(2)))) * (2 ^ (23 - Int(Log(Abs(MyInteger)) / Log(2))))
    
    End If
Nahlásit jako SPAM
IP: 213.129.136.–
Jakub Kohout
~ Anonymní uživatel
4 příspěvky
16. 5. 2014   #8
-
0
-

#7 pee-jay_cz
Dík moc za všechnu tvojí práci a rady, s tímhle to rozchodím na 100% :) Jseš borec

Nahlásit jako SPAM
IP: 85.70.141.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 59 hostů

Podobná vlákna

Float to int — založil Atmega_uset

Převod TString do int — založil Garones

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý