-         

Ergebnis 1 bis 8 von 8

Thema: formatierte Single-Ausgabe

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67

    formatierte Single-Ausgabe

    Anzeige

    Hallo Forum,

    zur übersichtlichen Zahlenausgabe auf LCD und über UART habe ich mir eine Funtion programmiert, welche mir einen Single-Wert in einen String umwandelt, unter Beachtung von Rundung sowie der Vorgabe der Anzahl der Vorkomma- und Nachkommastellen.

    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $framesize = 120                                           
    $swstack = 120
    $hwstack = 120
    $baud = 57600
    $sim
    
    Declare Function Ausgabe(byval _x As Single , Byval _v As Byte , Byval _n As Byte) As String
    
    
    Dim Ausgabe_string As String * 20
    Dim Ausgabe_string_zeichen(21) As Byte At Ausgabe_string Overlay
    Dim Zahl As Single : Zahl = -0.2
    Dim Restzeit As Long : Restzeit = 0
    
    Do
       Zahl = Zahl + 0.1
       Print Ausgabe(zahl , 3 , 3)
    Loop
    End
    
    
    
    Function Ausgabe(byval _x As Single , _v As Byte , _n As Byte) As String
    '_v = Anzahl Vorkommastellen ; _n = Anzahl Nachkommastellen
    Local _string As String * 15 : _string = ""
    Local _laenge As Byte
    Local _zaehler As Byte : _zaehler = 0
    Local _faktor As Long : _faktor = 1
    Local _nachkomma_string As String * 10
    Local _vorkomma_string As String * 10
    Local _anz_zeichen As Byte
    Local _minus As Byte
    
        While _zaehler <> _n
           _faktor = _faktor * 10
           Incr _zaehler
        Wend
        _x = _x * _faktor
        _x = Round(_x)
    
        If _x >= 0 Then                                         'bei x=0 springt der Simulator in Else-Zweig
              _minus = 0
           Else
              _minus = 1
              _x = Abs(_x)
        End If
    
        Ausgabe_string = Str(_x)
        _laenge = Len(ausgabe_string)
        _laenge = _laenge - 2
        Ausgabe_string = Left(ausgabe_string , _laenge)         '".0" abschneiden
    
        If Ausgabe_string <> "0" Then _nachkomma_string = Right(ausgabe_string , _n) Else _nachkomma_string = "0"
    
        _anz_zeichen = _v + _n
        While _laenge < _anz_zeichen
             Ausgabe_string = "0" + Ausgabe_string
             _laenge = Len(ausgabe_string)
        Wend
    
        _vorkomma_string = Left(ausgabe_string , _v)
    
        If _minus = 1 Then _string = "-" Else _string = " "
        _string = _string + _vorkomma_string
        _string = _string + ","
        _string = _string + _nachkomma_string
    
        Ausgabe = _string
    End Function

    Funktionieren tut es im Simulator - jedoch wird die 0 als Wert nicht erkannt.
    Ich habe die Stelle kommentiert - es wird laut Simulator in den Else-Zweig gesprungen, was dann zur Folge hat, dass mir -0 ausgegeben wird.

    Ich hab mir ziemlich schwer getan mit dieser Funktion - hat vielleicht jemand eine bessere, schnellere, ressourcenschonendere?

    besten Dank


    BoGe-Ro

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    mit direkten = Vergleichen ist es bei singles + floats so eine Sache.
    Lass dir im Simualtor die x-variable als Hex ausgeben. Ob denn auch wirklich NULL drinsteht.

    du kannst dein "If" testen, indem du mal definitv 0.0 in das Single schreibst. das sollte ja schon gehen.

    Ich persönlich würde x von Bascom erst ganz normal in einen String umwandeln lassen, und dann zur Formatierung in diesem String rumwerken.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Was stört dich an dem FUSING Befehl?
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67
    Hallo,

    ursprünglich wollte ich auch eine Lösung mit FUSING erreichen.
    die gefundenen Nachteile dabei waren:
    - Dezimalpunkt statt Komma
    - da der Fusing-Befehl wohl keine String-Variable als Maske akzeptiert, muss für jede Anzahl von Nachkommastellen eine IF-Abfrage, bzw. Case-Auswahl entstehen und ein extra Fusing-Befehl geschrieben werden
    - die Anzahl der Stellen vor dem Komma beeinflusst der Fusing-Befehl gar nicht


    Gruß

    BoGe-Ro

  5. #5
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Ich hab' deiner Function ein paar printout's eingefügt. Du siehst, dass auch nach dem round ein -0.0 rauskommt.
    (der Simulator besch..t dich da)
    Code:
        While _zaehler <> _n
           _faktor = _faktor * 10
           Incr _zaehler
        Wend
        Print "IN:" ; _x ; "->";
        _x = _x * _faktor
        Print "*fak:" ; _x ; "->";
        _x = Round(_x)
       Print "rounded:" ; _x
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Du kannst nach den faktor-erweitern und vor der <= 0 abfrage eine Abfrage einfügen, ob die Zahl überhaupt <> 0 ist, egal ob + oder -

    und dann auf definitiv +0.0 setzen
    Code:
        While _zaehler <> _n
           _faktor = _faktor * 10
           Incr _zaehler
        Wend
        _x = _x * _faktor
    
        If _x < 1.0 And _x > -1.0 Then        '  -1.0  < _x < +1.0  
             _x = 0.0
        End If
    
        If _x >= 0 Then
          _minus = 0
        Else
          _minus = 1
          _x = Abs(_x)
        End If
    
        _x = Round(_x)
    
        If Ausgabe_string <> "0" Then _nachkomma_string = Right(ausgabe_string , _n) Else _nachkomma_string = "0"
    
    ----etc----
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67
    jo, habs gerade mal durchsimuliert...

    Simulator hat in den Locals eine glatte 0, gibt aber selber eine -0.0 als Printout aus.

    ist irgendwie nicht konsistent....

    jedenfalls lässt sich auf diese -0.0 checken - zumindest solang nichts an dieser Round-Funktion verändert wird.

    Ein weiterer Fehler war ausserdem noch drin - wenn der Nachkommastring kleiner war, also der Nachkomma-Anteil ursprünglich führende Nullen hatte.

    Ist jetzt gefixt und sieht so aus:

    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $framesize = 120                                           
    $swstack = 120
    $hwstack = 120
    $baud = 57600
    $sim
    
    Declare Function Ausgabe(byval _x As Single , Byval _v As Byte , Byval _n As Byte) As String
    
    Dim Ausgabe_string As String * 20
    Dim Ausgabe_string_zeichen(21) As Byte At Ausgabe_string Overlay
    Dim Zahl As Single : Zahl = -1
    
    Do
       Print Zahl ; " rund " ; Ausgabe(zahl , 2 , 1)
       Zahl = Zahl + 0.01
    Loop
    End
    
    
    
    
    
    Function Ausgabe(byval _x As Single , _v As Byte , _n As Byte) As String
    '_v = Anzahl Vorkommastellen ; _n = Anzahl Nachkommastellen
    Local _string As String * 15 : _string = ""
    Local _laenge As Byte
    Local _zaehler As Byte : _zaehler = 0
    Local _faktor As Long : _faktor = 1
    Local _nachkomma_string As String * 10
    Local _vorkomma_string As String * 10
    Local _anz_zeichen As Byte
    Local _minus As Byte
    
        While _zaehler <> _n
           _faktor = _faktor * 10
           Incr _zaehler
        Wend
        'Print "IN:" ; _x ; "->";
        _x = _x * _faktor
        'Print "*fak:" ; _x ; "->";
        _x = Round(_x)
        'Print "rounded:" ; _x
    
        If _x >= 0 Or _x = -0.0 Then                            'bei x=0 springt der Simulator in Else-Zweig
              _minus = 0
           Else
              _minus = 1
        End If
        _x = Abs(_x)
    
        Ausgabe_string = Str(_x)
        _laenge = Len(ausgabe_string)
        _laenge = _laenge - 2
        Ausgabe_string = Left(ausgabe_string , _laenge)         '".0" abschneiden
    
        _laenge = Len(ausgabe_string)
        _anz_zeichen = _n
        While _laenge < _anz_zeichen
             Ausgabe_string = "0" + Ausgabe_string
             _laenge = Len(ausgabe_string)
        Wend
        _nachkomma_string = Right(ausgabe_string , _n)
    
        _anz_zeichen = _v + _n
        While _laenge < _anz_zeichen
             Ausgabe_string = "0" + Ausgabe_string
             _laenge = Len(ausgabe_string)
        Wend
    
        _vorkomma_string = Left(ausgabe_string , _v)
    
        If _minus = 1 Then _string = "-" Else _string = " "
        _string = _string + _vorkomma_string
        If _n > 0 Then
              _string = _string + ","
              _string = _string + _nachkomma_string
        End If
    
        Ausgabe = _string
    End Function

    mfG
    BoGe-Ro

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.02.2010
    Beiträge
    167
    Nimm AVR-Studio als Simulator.

    Vergess das Ding von Bascom.

    gruss

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •