Float to String - wie?



  • Schon wieder ich!
    Ich versuche schon die ganze Zeit eine Gleitkommazahl(4 Byte) in einen Text zu konvertieren. Allerdings geht das nicht mit wsprintf, mit der ich Integer in Strings umwandle. Hat jemand ne Idee wie das gehen könnte.



  • Doch, geht mit wsprintf. Nimm statt %i oder %d (int) einfach %f (float).



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum Assembler in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • also bei mir funktioniert das nicht, einmal davon abgesehen, dass es in der MSDN nicht aufgeführt ist.

    format PE GUI 4.0
    entry Main
    include '\INCLUDE\win32a.inc'
    
    section '.data' data readable writeable
       flt dd 1.2
       fMtStrinG db "%f",0
       leer db 0
    section '.code' code readable executable
       Main:
          push [flt]
          call FloatToStr
    
          push 64
          push leer
          push eax
          push 0
          call [MessageBox]
          push 0
          call [ExitProcess]
          ret
       proc FloatToStr val:DWORD
          push 20
          push HEAP_ZERO_MEMORY
            call [GetProcessHeap]
            push eax
          call [HeapAlloc]
          push eax
            push [val]
            push fMtStrinG
            push eax
            call [wsprintf]
          pop eax
          ret
       endp
    
    section '.idata' import data readable writeable
    library kernel,"kernel32.dll",\
            user,"user32.DLL"
    import kernel,\
           ExitProcess,"ExitProcess",\
           GetProcessHeap,"GetProcessHeap",\
           HeapAlloc,"HeapAlloc"
    import user,\
           MessageBox,"MessageBoxA",\
           wsprintf,"wsprintfA"
    


  • wsprintf mit MessageBox? 😕



  • Der Code wandelt eine(n?) Float in einen String mithilfe von wsprintf und gibt diesen mit MessageBox aus.



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum ANSI C in das Forum Assembler verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Wenn du dort nun mit Assembler anfaengst, ist das bei C fehl am Platz - sorry, mein Fehler. 😉

    edit - um noch etwas zum Thema gesagt zu haben:
    Bestimmt gibt es irgendeine WinAPI-Funktion, die so etwas kann (gibt dort schliesslich Funktionen fuer jeden kleinen Mist) - kenne ich aber nicht.
    wsprintf kann scheinbar kein %f.

    Du kannst dir natuerlich auch recht schnell und einfach selbst eine Funktion schreiben:
    Die fpu hat die schoene Instruktion "fist", die dir einen gerundeten Integer liefert. Rundungsregeln musst du vorher im control-word AFAIR so einstellen, dass der Nachkommateil dabei einfach abgeschnitten wird.
    So kriegst du erstmal einfach den Teil vor dem Komma, setzt dann den Punkt, berechnest dir den Rest nach dem Komma (einfach durch Subtraktion), paar mal mit 10 multiplizieren - je nachdem, wie viele Stellen du anzeigen willst - nochmal fist, fertig. Die beiden Integer in einen String zu wandeln ist wirklich trivial, dazu braucht man IMHO keine WinAPI.



  • Ich hab mal versucht den Vorschlag umzusetzen, aber ich glaub des is mir ne Nummer zu groß. Gibt es irgendwo eine Tabelle in der die control-words stehen, und warum stürzt das Programm ab?

    format PE GUI 4.0
    entry Main
    include 'INCLUDE\win32a.inc'
    
    section '.data' data readable writeable
       float1 dd 123.45
    
    section '.code' code readable executable
       proc Main
          push [float1]
          call FloatToStr
          push 0
          call [ExitProcess]
          ret
       endp
       szTemp: db 30 dup 0
       proc FloatToStr float:DWORD
          local iNumber:DWORD,iKomma:DWORD
          mov esi,[szTemp]
          cmp [float],0
          jne Ab1
             mov byte [esi],"0"
             inc esi
             mov byte [esi],0
             inc esi
             jmp ende
          Ab1:
          ;set control word ??
          fld [float]
          fist [iNumber]   ;absturz!!
          fld [float]
          fsub [iNumber]
          call Teste
          push [iNumber]
          call NumToStr
          call Teste
          mov byte [esi],"."
          inc esi
          mov eax,1000000
          fmul dword [eax]
          fist [iKomma]
          push [iKomma]
          call NumToStr
          call Teste
          ende:
          push 64
          push 0
          push szTemp
          push 0
          call [MessageBox]
          ret
       endp
    
       proc NumToStr Num:DWORD
          push [Num]
          push fMtStrinG
          push esi
          call [wsprintf]
          anf:
          inc esi
          cmp byte [esi],0
          jne anf
          ret
       endp
       fMtStrinG: db "%ld",0
    section '.idata' import data readable writeable
    library kernel,'kernel32.dll',\
            user,'user32.dll'
    import kernel,\
           GetProcessHeap,"GetProcessHeap",\
           HeapAlloc,"HeapAlloc",\
           ExitProcess,'ExitProcess'
    import user,\
           MessageBox,'MessageBoxA',\
           wsprintf,"wsprintfA"
    

    edit: komisch die schließenden doppelten Anführungszeichen werden im Beitrag immer als einfache dargestellt



  • Sorry, war mir nicht so recht bewusst, dass wsprintf in diesem Fall versagt (obwohl ich das irgendwie doch schon mal gehört hab 🤡 ). Dann eben sprintf und den String dann per %s in den wchar_t 'rein. Oder eben dein ASM-Ansatz... 🙂


Anmelden zum Antworten