Byte & Integer

polar

Mitglied
hi! habe folgendes prob:

ich schreibe daten (meistens zahlen bis 255) byteweise in eine datei. leider habe ich das problem, das ich eine zahl habe, die größer ist als 255. wenn ich diese zahl als integer in die datei schreibe, bekomme ich einen total falschen wert. wie kann ich den integer in zwei bytes aufteilen?? also erst die eine hälfte des int's schreiben, dann die andere.. ?? geht das ??

danke im vorraus :)
 
ich hab zwar keine besonders elegante lösung dafür, aber immerhin funktioniert es. du musst erstmal deine zahl ins binärsystem übertragen:
Code:
Dim i As Integer
Dim b As String

i = 777
Do While i > 0
    If i Mod 2 <> 0 Then
        b = "1" & b
    Else
        b = "0" & b
    End If
    i = i \ 2
Loop

MsgBox b

von jetzt an bieten sich dir zwei möglichkeiten. entweder du speicherst die binären werte als text - aber das ist zugegebenermassen keine besonders tolle lösung. oder du nimmst dir daraus einfach deine beiden byte-werte:
wenn der string mit dem binärwert der zahl dann länger als 8 zeichen ist, legst du einfach die letzten 8 zeichen in variable x und die restlichen zeichen in variable y ab. in dem beispiel wäre variable x = "00001001" und y = "11".

dann erzeugst du aus deinen beiden binärwerten wieder zwei "richtige" zahlen:
Code:
Dim b As String
Dim i As Integer
Dim c As Integer 'zählervariable

b = "1001"
For c = 1 To Len(b)
    i = i + CInt(Mid(b, c, 1) * 2 ^ (c - 1))
Next c

MsgBox CStr(i)

und schon hast du zwei ganze zahlen, die beide in eine byte-variable passen. wenn du dazu noch fragen hast, meld dich nochmal.
 
noch was vergessen...

es wäre natürlich auch praktisch, das später wieder zurück zu rechnen. um nochmal die werte aus dem beispiel zu benutzen:
11 = 3
00001001 = 9

Code:
ergebnis binär  : 11 + (11 * 11111111) + 00001001 = 1100001001
ergebnis dezimal:  3 + ( 3 *      255) +        9 =        777
 
ne andere Möglichkeit

Ich hätte da noch ne andere Möglichkeit anzubieten.

Zum "zerteilen" in erstes und zweites Byte:
Code:
Dim high as byte, low as byte

'X ist das Integer
'erstes Byte
high = (X And &HFF00) - &HFF
'zweites Byte
low = X And &HFF
Das ergibt zB für 312 high = 1 und low = 56. Die beiden Zahlen einfach in die Datei schreiben.

Beim Einlesen wird wieder "zusammengesetzt":
Code:
'... high und low werden eingelesen

X = (high + &HFF) Or low
Für high = 1 und low = 56 ergibt das wieder 312.

Zur Erklärung: 312 ist binär 1|00111000, was mehr als 8Bit, also ein Byte ist (Markiert durch senkrechten Strich). Mit der oben vorgestellten Methode trennt man den Teil, der im ersten Byte liegt - also 1 - von dem im zweiten Byte - also 111000 (56).

-Crayzee Ivan
 
die möglichkeit ist zwar wesentlich kürzer, und auch vom ansatz her besser gedacht als meine - allerdings funktioniert das nur mit zahlen kleiner als 512, bei allen darüber gibt es einen speicherüberlauf.

meine variante war auch eher auf den rechnerischen weg ausgearbeitet und wie gesagt nicht unbedingt das absolute nonplusultra - aber es funktioniert (mehr oder weniger jedenfalls :rolleyes: ).
noch eine möglichkeit wäre bitweises verschieben, was ja der multiplikation/division mit 2 entspricht.
 
hmm..

vielecht gehts auch noch anders, ich spezifizier nochmal:

also meine variablen sind alle vom type byte. die zahlen die ich mit "Put" in die binär geöffnete datei schreibe liegen alle im bereich 0 - 255, also kein problem. strings schreibe ich zeichenweise in die datei, auch kein problem. allerdings habe ich eben noch eine variable die, die anzahl der gesamten daten beinhaltet. die kann eigentlich 0 - unendlich groß sein. dürfte aber nich über 60.000 gehen =) also ist ein integer ausreichend. wenn ich jetzt den int mit "Put" in die datei schreibe sieht es für mich so aus als würde er nur ein byte schreiben. aber laut der hilfe, sollte das trotzdem funzen. "Print" geht auch nicht und "Write" kann ich eh vergessen.

warum kann ich mit "Put" den integer nicht korrekt schreiben???

asphyxia: ich probier gleich mal deine methode aus.

danke nochmal :)
 
klappt nicht

asphyxia: mit deiner methode bekomm ich das nicht ganz hin. wenn ich meiner funktion folgenden string übergebe "393" bekomme ich als einzelne werte nur "0" und "3" zurück. ich poste mal den code...

mein type:

PHP:
Type Word

     Lower As Byte
     Upper As Byte
     
End Type

meine funktion:

PHP:
Private Function IntSpalter(doomedVar As String)
Dim by As String
Dim by1 As String
Dim by2 As String
Dim i As Integer
Dim Data_Word As Word

i = Len(doomedVar)
    
    Do While i > 0
        If i Mod 2 <> 0 Then
            by = "1" & by
        Else
            by = "0" & by
        End If
        i = i \ 2
    Loop
    
If Len(by) > 8 Then
    by1 = Mid(by, 1, 8)
    
    For i = 1 To Len(by1)
        Data_Word.Lower = Data_Word.Lower + CInt(Mid(by1, i, 1) * 2 ^ (i - 1))
    Next i
    
    by2 = Mid(by, 9, Len(doomedVar))
    
    For i = 1 To Len(by2)
        Data_Word.Upper = Data_Word.Upper + CInt(Mid(by2, i, 1) * 2 ^ (i - 1))
    Next i
    
Else
    Data_Word.Lower = 0
    
    For i = 1 To Len(by)
        Data_Word.Upper = Data_Word.Upper + CInt(Mid(by, i, 1) * 2 ^ (i - 1))
    Next i
    
End If

'IntSpalter (Data_Word)
MsgBox CStr(Data_Word.Lower)
MsgBox CStr(Data_Word.Upper)
End Function

hoffe das schafft etwas klarheit :)

edit: mit den PHP tags klappt die darstellung nicht so ganz.
End Type und End Function fehlt irgendwie *g*
 
Zuletzt bearbeitet:
@asphyxia: Mist :mad:. Das war eigentlich nur ne alte Funktion, aber offensichtlich hab ich der nie Zahlen übergeben, die größer als 511 waren :(. Als beste Lösung bleibt dann wohl nur noch das Byte-Shiften, aber da weiß ich jetzt nicht genau, wie man das in VB realisieren könnte.

@polar: Ich habe ein paar Fehler in deiner Funktion gefunden und korrigiert, folgendes sollte funktionieren:
Code:
Private Function IntSpalter(doomedVar As String)
Dim by As String
Dim by1 As String
Dim by2 As String
Dim i As Integer
Dim Data_Word As Word

i = Val(doomedVar)
'gesucht war der Zahlenwert, nicht die Länge, also Val statt Len
    
    Do While i > 0
        If i Mod 2 <> 0 Then
            by = "1" & by
        Else
            by = "0" & by
        End If
        i = i \ 2
    Loop
    
If Len(by) > 8 Then
    by1 = Right$(by, 8)
    
    For i = 1 To 8
        Data_Word.Lower = Data_Word.Lower + CInt(Mid(by1, (8 + 1) - i, 1) * 2 ^ (i - 1))
        'Die Strings wurden falsch rum ausgelesen, die abarbeitung
        'der Binärzahlen muss von hinten anfangen. Das fiel bei 
        'asphyxias Beispiel nicht auf, weil "1001" von hinten und 
        'vorne das selbe ist.
    Next i
    
    by2 = Left$(by, Len(by) - 8)
    
    For i = 1 To Len(by2)
        Data_Word.Upper = Data_Word.Upper + CInt(Mid(by2, (Len(by2) + 1) - i, 1) * 2 ^ (i - 1))
    Next i
    
Else
    Data_Word.Lower = 0
    
    For i = 1 To Len(by)
        Data_Word.Upper = Data_Word.Upper + CInt(Mid(by, (Len(by) + 1) - i, 1) * 2 ^ (i - 1))
    Next i
    
End If

'IntSpalter (Data_Word)
MsgBox CStr(Data_Word.Lower)
MsgBox CStr(Data_Word.Upper)
End Function

-Crayzee Ivan
 
Zuletzt bearbeitet:
kewl

danke für deine korrektur ivan :)

wenn ich jetzt by1 und by2 mit der MsgBox zum testen ausgeben lasse, bekomme ich folgende werte: "137" und anschliessend "1" *fg* klappt doch nicht so ganz.
 

Neue Beiträge

Zurück