VB2008 Zahl von Kleinsteuerung konvertieren 65534 = -0.2?

Gast #3022599
Lesenswert?

Hallo Leute,

Logge bei einer Kleinsteuerung auf eine MicroSD Karte.
Leider ist bei dieser Chinesensteuerung kein vernünftiger Support 
gegeben.

Darum muss ich mir selbst ein Programm zum einlesen und konvertiren in 
CSV schreiben. Wie kann ich aber folgende Wertetabelle vernünftig 
konvertiren ???

6  = 0.6
5  = 0.5
4       = 0.4
3  = 0.3
2  = 0.2
1  = 0.1
0  = 0.0
65535   =-0.1
65534   =-0.2
65533   =-0.3
65532   =-0.4
65531   =-0.5

Habe es wie folgt probiert, aber leider rundet mir VB was weg.

    Function CorrectNumber(ByRef Analogflag As String) As String
        Dim Zahl As Double

        Zahl = Val(Analogflag)
        If Zahl >= 32767 Then
            CorrectNumber = ((65535 - Zahl) * -1) / 10
        Else
            CorrectNumber = Analogflag / 10
        End If
    End Function

Weis jemand Rat?
#3022608
Lesenswert?

Schaut so aus als ob das ein 16 bit Integer mit Fixed-Point ist.
1
Dim Zahl As Integer
2
Zahl = Val(Analogflag)
3
If Zahl >= 32767 Then Zahl = Zahl - 65536
4

5
CorrectNumber = CStr(Zahl / 10)
6
' oder
7
CorrectNumber = CStr(Zahl div 10) + "." + CStr(abs(Zahl mod 10))

(Ob das korrektes VB ist, weiß ich nicht)

Gruß
Roland
#3022634
Lesenswert?

Hallo,

also im vorgenannten Text muß Zahl natürlich als Long definiert werden, 
sonst läuft der Wert bereits bei der VAL-Funktion über.

Integer ist niemals größer als 32767 !

Übrigens ist die Darstellung des Dezimalkommans als "." oder "," hier 
abhängig von den Einstellungen der Locales des Users, sollte man so 
nicht formulieren.

Gruß,
Michael
Gast #3022651
Lesenswert?

Bin ein bischen schlauer geworden:

5  = 0.5 = 0000000000000101
4       = 0.4 = 0000000000000100
3  = 0.3 = 0000000000000011
2  = 0.2 = 0000000000000010
1  = 0.1 = 0000000000000001
0  = 0.0 = 0000000000000000
65535   =-0.0 = 1111111111111111
65534   =-0.1 = 1111111111111110
65533   =-0.2 = 1111111111111101
65532   =-0.3 = 1111111111111100
65531   =-0.4 = 1111111111111011

Aber wie in VB ordentlich lösen?

Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl -> Zahl / 
10
Gast #3022676
Lesenswert?

Habe gerade folgende probiert:

Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl ->
Zahl = Zahl * -1 -> Zahl / 10

Das funktioniert.

Müsste doch irgendwie ohne Umweg zu binär gehen, oder?
#3022720
Lesenswert?

Katastrophe schrieb:
> Von der SD Karte lese ich Integer Werte in einer TXT Datei.

wie genau liest du ein.

Wenn du in eine 16 Bit vorzeichenbehaftete Integer Variable (wie auch 
immer dieser Datentyp im VB heißt) die beiden Bytes direkt einliest, 
brauchst du normalerweise überhaupt nichts tun.

Denn die Bytes (jetzt mal abgesehen von der Bytereihenfolge) sind schon 
im 2-er Komplement, welches auch dein 16-Bit Integer mit Vorzeichen 
benutzt.

Du machst dir da zu viel Arbeit und verkomplizierst die Dinge unnötig.
Gast #3022755
Lesenswert?

Lese mit System.IO.File.ReadAllLines ein.
Diese werden in eine Listbox kopiert, weil die einzelnen Zeilen noch "0" 
und "1" für Relais und andere Zustände der Kleinsteuerung enthalten.
Darum kann ich es nicht besser einlesen.
Gast #3022759
Lesenswert?

Katastrophe schrieb:
> Diese werden in eine Listbox kopiert, weil die einzelnen Zeilen noch "0"
> und "1" für Relais und andere Zustände der Kleinsteuerung enthalten.
> Darum kann ich es nicht besser einlesen.

was soll denn das für ein Grund sein. eine Listbox ist ein GUI element 
das nimmt man nicht für eine Datenverarbeitung. Was ist wenn dein 
Programm kein Gui hat?

Kannst du mal so eine Textdatei hochladen?
#3023997
Lesenswert?

Katastrophe schrieb:
> Habe mal die Dateien angehangen.

Noch größere hast du nicht gefunden?

Mann, mann, mann.
Bissi mitdenken! Keiner hier wusste, dass deine Dateien so groß sind. In 
diesem Fall hätte es ein Auszug aus dem Dateianfang auch getan. Wir 
wollen doch nur sehen, wie die prinzpiell aussehn, mehr nicht.
Und dafür lad ich mir sicher nicht 25MB runter.

Ganz davon abgesehen, dass eine 'kleine Version' der Daten auch während 
der Programmentwicklung nützlich ist. Oder willst du während der 
Entwicklung laufend riesige Files wieder und immer wieder einlesen?
Gast #3024750
Lesenswert?

axelr schrieb:
> 65534 -> StrToInt -> / 10

Würde dann aber 6553.4 ergeben :-(

Sorry wegen der Grösse.
Habe ich bei VDSL übersehen ;-)

Die Felder mit den >65000 sind gefragt. Codierung wie schon oben 
beschrieben:
Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl ->
Zahl = Zahl * -1 -> Zahl / 10
#3025066
Lesenswert?

Kriegst Du die Textdatei in genau der Form oder hast Du die schon 
bearbeitet?
Denn da steht ja gar nicht 65535 drin, sondern schon 6553.5. Ist das 
Komma original?
Das dämlichste, was den Daten auf dem Weg in diese Darstellung passiert 
ist, ist ja, dass ein 16 signed int (der * .1 skaliert zu interpretieren 
ist) als 16-bit unsigned int (und dann evtl. schon * .1 skaliert ist) 
ausgegeben wird.
So oder so:

1. Komma entfernen, falls es nicht erst durch Dich da rein gekommen ist
2. Textdarstellung in 16-bit unsigned int umwandeln
3. Ergebnis von #2 brutal nach 16-bit signed int casten
4. Ergebnis von #3 unter Umwandlung in Fest- oder Fließkomma durch 10 
teilen

Schritte #2-#4 in C:

(int16_t)strtoul(string_value_without_decimal_point, NULL, 10) / 10.0

Schritt #3 ist der alles entscheidende. Ob VB zu dieser Verrenkung in 
der Lage ist, ohne eben über die Binärdarstellung zu gehen, weiß ich 
nicht. Aber vielleicht findest Du ja dazu was. Uminterpretation unsigned 
=> signed.
Gast #3391956
Lesenswert?

Hey Leute.

Scheinbar nehme ich die gleiche Steuerung her :-D

Selbes Problem, selbe Sprache (VB2010).

Habe es wie folgt gelöst:
1
    Public Function CorrectNumber(ByVal StringNumber As String) As Double 'Richtigen Wert ermitteln
2
        Dim helpstring As String
3
        helpstring = StringNumber.Replace(".", "")      'String übergeben und Punkte entfernen
4
        If Int(StringNumber < 32767) Then
5
            CorrectNumber = Int(StringNumber) / 10
6
        Else
7
            helpstring = Decimal2Binary(Int(StringNumber))  'In Binär wandeln
8
            helpstring = helpstring.Replace("0", "T") 'Bin Wert invertieren
9
            helpstring = helpstring.Replace("1", "0") 'Bin Wert invertieren
10
            helpstring = helpstring.Replace("T", "1") 'Bin Wert invertieren
11
            CorrectNumber = Binary2Decimal(helpstring) / -10 'In Integer wandeln und minusvorzeichen setzen
12
        End If
13
    End Function
14

15

16
    ' Dezimal nach Binärzahl umwandeln
17
    Public Function Decimal2Binary(ByVal Dec As Integer) As String
18
        Return Convert.ToString(Dec, 2)
19
    End Function
20

21
    ' Binärzahl nach Dezimal umwandeln
22
    Public Function Binary2Decimal(ByVal Bin As String) As Integer
23
        Dim l As Integer
24

25
        For i As Integer = 0 To Bin.Length - 1
26
            l = (l << 1) + Integer.Parse(Bin.Substring(i, 1))
27
        Next
28
        Return l
29
    End Function

Würde trotzdem einen kürzeren Code als angenehm entfinden :-D
#3392977
Lesenswert?

Ich kann mir nicht vorstellen, dass das hier
1
        If Int(StringNumber < 32767) Then
korrekt ist.

Warum ihr da unbedingt über binär gehen müsst erschliesst sich mir 
überhaupt nicht.
Selbst wenn ein int in VB mitlerweile 32 Bit groß ist, wo genau liegt 
jetzt das Problem in
1
   Zahl = int( string )
2

3
   if( Zahl > 32767 )
4
     Zahl = Zahl - 65536
5

6
   Ergebnis = Zahl / 10

Das die Gleitkommadarstellung der Zehntel nicht immer 100% exakt ist, 
liegt an der Gleitkommadarstellung an sich und muss in den weiteren 
Berechnungen berücksichtigt werden.
#3393255
Lesenswert?

Kurt schrieb:
> Arc Net schrieb:
>> Zwar C#
>> double d = Convert.ToInt16("1111111111111110", 2) / 10.0;
>> bzw.
>> double d = (Int16)Convert.ToUInt16(65535) / 10.0;
>
> Das geht unter VB schief !!!

Ja, hatte tatsächlich vergessen, dass so was in VB einen Overflow 
ergibt...
Dann die Holzhammermethode...
1
BitConverter.ToInt16(BitConverter.GetBytes(Convert.ToUInt16(65535)), 0) / 10.0

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren