Differenze tra le versioni di "Ottenere un numero dalla sua memorizzazione in formato Big-Endian"

Da Gambas-it.org - Wikipedia.
Riga 12: Riga 12:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
 
  <FONT Color=gray>' ''Leggerà fino alla fine del file, quindi i tre byte:''</font>
 
  <FONT Color=gray>' ''Leggerà fino alla fine del file, quindi i tre byte:''</font>
  While Not Eof(fl)
+
  While Not Eof(fl)
    Read #fl, c
+
  Read #fl, c
    i = Shl(i, 8) Or c
+
  i = Shl(i, 8) Or c
  Wend
+
  Wend
 
    
 
    
  Print i
+
  Print i
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
 
  '''End'''
 
  '''End'''
 
 
oppure: <SUP>&#091;[[#Note|Nota 1]]&#093;</sup>
 
oppure: <SUP>&#091;[[#Note|Nota 1]]&#093;</sup>
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
Riga 33: Riga 32:
 
   Dim a, b As Byte
 
   Dim a, b As Byte
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  For a = 0 To 2
+
  For a = 0 To 2
    Read #fl, b
+
    Read #fl, b
    i += b * 2 ^ (8 * (2 - a))
+
    i += b * 2 ^ (8 * (2 - a))
  Next
+
  Next
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 54: Riga 53:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  For c = 2 To 0 Step -1
+
  For c = 2 To 0 Step -1
    Read #fl, b
+
    Read #fl, b
    i += b * 2 ^ (8 * c)  <FONT Color=gray>' ''o anche: i += Shl(CInt(b), 8 * c)''</font>
+
    i += b * 2 ^ (8 * c)  <FONT Color=gray>' ''o anche: i += Shl(CInt(b), 8 * c)''</font>
  Next
+
  Next
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
 
+
o anche:
oppure:
 
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
Riga 74: Riga 72:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  Read #fl, c
+
  Read #fl, c
  i = CInt(c)
+
  i = CInt(c)
 
    
 
    
  For b = 1 To 2
+
  For b = 1 To 2
    Read #fl, c
+
    Read #fl, c
    i = Shl(i, 8)
+
    i = Shl(i, 8)
    i = i Or (c And 127)
+
    i = i Or (c And 127)
  Next
+
  Next
 
    
 
    
  Print i
+
  Print i
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
 
  '''End'''
 
  '''End'''
 
 
oppure usando le risorse ''stringa'' con successiva conversione in valore numerico in rappresentazione decimale:
 
oppure usando le risorse ''stringa'' con successiva conversione in valore numerico in rappresentazione decimale:
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
Riga 98: Riga 95:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
 
  <FONT Color=gray>' ''Legge tre byte:''</font>
 
  <FONT Color=gray>' ''Legge tre byte:''</font>
  Read #fl, s, 3
+
  Read #fl, s, 3
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  s = Hex(Asc(s, 1), 2) & Hex(Asc(s, 2), 2) & Hex(Asc(s, 3), 2)
+
  s = Hex(Asc(s, 1), 2) & Hex(Asc(s, 2), 2) & Hex(Asc(s, 3), 2)
 
    
 
    
  i = Val("&" & s)
+
  i = Val("&" & s)
 
    
 
    
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
  
  
====Usando un vettore di tipo Byte[] come appoggio====
+
===Usando un vettore di tipo Byte[] come appoggio===
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
Riga 121: Riga 118:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
 
  <FONT Color=gray>' ''Legge i tre byte:''</font>
 
  <FONT Color=gray>' ''Legge i tre byte:''</font>
  bb.Read(fl, 0, bb.Count)
+
  bb.Read(fl, 0, bb.Count)
  bb.Reverse()
+
  bb.Reverse()
 
    
 
    
  i = Int@(bb.Data)
+
  i = Int@(bb.Data)
 
    
 
    
  Print i
+
  Print i
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 142: Riga 139:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  bb.Read(fl, 0, bb.Count)
+
  bb.Read(fl, 0, bb.Count)
 
    
 
    
  fl.Close
+
  fl.Close
+
 
  i = bb[2]
+
  i = bb[2]
  i += bb[1] * 256            <FONT Color=gray>' ''&0100''</font>
+
  i += bb[1] * 256            <FONT Color=gray>' ''&0100''</font>
  i += bb[0] * 65536        <FONT Color=gray>' ''&010000''</font>
+
  i += bb[0] * 65536        <FONT Color=gray>' ''&010000''</font>
 
    
 
    
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 163: Riga 160:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  bb.Read(fl, 0, bb.Count)
+
  bb.Read(fl, 0, bb.Count)
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  i = (bb[2] Or ((bb[1] * CInt(2 ^ 8)))) Or (bb[0] * CInt(2 ^ 16))
+
  i = (bb[2] Or ((bb[1] * CInt(2 ^ 8)))) Or (bb[0] * CInt(2 ^ 16))
 
    
 
    
 
  <FONT Color=gray>' ''oppure anche così:''
 
  <FONT Color=gray>' ''oppure anche così:''
 
  '    '''(bb[2] Or (Shl(CInt(bb[1]), 8))) Or Shl(CInt(bb[0]), 16)'''</font>
 
  '    '''(bb[2] Or (Shl(CInt(bb[1]), 8))) Or Shl(CInt(bb[0]), 16)'''</font>
 
      
 
      
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
 
+
oppure usando le risorse ''stringa'' con successiva conversione in valore numerico
o usando le risorse ''stringa'' con successiva conversione in valore numerico in rappresentazione decimale:
 
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
Riga 186: Riga 182:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
+
  fl = Open "<FONT Color=gray>''/percorso/del/file''</font>" For Read
 
    
 
    
  bb.Read(fl, 0, bb.Count)
+
  bb.Read(fl, 0, bb.Count)
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  s = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
+
  s = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
 
    
 
    
  i = Val("&" & s)
+
  i = Val("&" & s)
 
      
 
      
  Print i
+
  Print i
 
    
 
    
 
  '''End'''
 
  '''End'''
 
  
  

Versione delle 15:17, 21 ott 2021

La circostanza è quella in cui si intende leggere i dati-byte di un valore all'interno di un file, memorizzati in formato Big-Endian a dimensione fissa, ottenendo così al termine della lettura l'effettivo numero corrispondente (ossia corrispondente esattamente alla disposizione dei dati-byte in formato Big-Endian).

Come sappiamo, se un valore è stato volutamente salvato in modalità Big-Endian all'interno di un file, la sua successiva lettura con un sistema, che opera con una modalità di memorizzazione dei dati in Little-Endian, non restituirà il valore esatto, ossia quello che si era volutamente memorizzato.
Così, ad esempio, se nel file è memorizzato il gruppo di tre byte-dati &h010305, corrispondente in rappresentazione decimale al numero 66309, una lettura in Little-Endian ruoterà i dati-byte di quel valore, come segue: &h050301, ordine di byte che corrisponde invece al numero 328449 !


Mostriamo alcune possibiità, con le quali poter restituire, dalla lettura da un file di suoi 3 dati memorizzati in Big-Endian, l'effettivo valore che fu a suo tempo memorizzato nel file.

Public Sub Main()

 Dim fl As File
 Dim c As Byte 
 Dim i As Integer
 
 fl = Open "/percorso/del/file" For Read
  
' Leggerà fino alla fine del file, quindi i tre byte:
 While Not Eof(fl)
  Read #fl, c
  i = Shl(i, 8) Or c
 Wend
  
 Print i
  
 fl.Close
 
End

oppure: [Nota 1]

Public Sub Main()
 
 Dim fl As File
 Dim i As Integer
 Dim a, b As Byte
  
 fl = Open "/percorso/del/file" For Read
  
 For a = 0 To 2
   Read #fl, b
   i += b * 2 ^ (8 * (2 - a))
 Next
  
 fl.Close
  
 Print i
  
End

oppure una piccola variante del codice precedente:

Public Sub Main()
 
 Dim fl As File
 Dim b As Byte
 Dim c As Short
 Dim i As Integer
  
 fl = Open "/percorso/del/file" For Read
  
 For c = 2 To 0 Step -1
   Read #fl, b
   i += b * 2 ^ (8 * c)   ' o anche: i += Shl(CInt(b), 8 * c)
 Next
  
 fl.Close
  
 Print i
  
End

o anche:

Public Sub Main()

 Dim fl As File
 Dim b, c As Byte 
 Dim i As Integer
  
 fl = Open "/percorso/del/file" For Read
  
 Read #fl, c
 i = CInt(c)
  
 For b = 1 To 2
   Read #fl, c
   i = Shl(i, 8)
   i = i Or (c And 127)
 Next
  
 Print i
  
 fl.Close
  
End

oppure usando le risorse stringa con successiva conversione in valore numerico in rappresentazione decimale:

Public Sub Main()

 Dim fl As File
 Dim s As String
 Dim i As Integer
  
 fl = Open "/percorso/del/file" For Read
  
' Legge tre byte:
 Read #fl, s, 3
  
 fl.Close
  
 s = Hex(Asc(s, 1), 2) & Hex(Asc(s, 2), 2) & Hex(Asc(s, 3), 2)
  
 i = Val("&" & s)
  
 Print i
  
End


Usando un vettore di tipo Byte[] come appoggio

Public Sub Main()

 Dim fl As File
 Dim bb As New Byte[3]
 Dim i As Integer
 
 fl = Open "/percorso/del/file" For Read
  
' Legge i tre byte:
 bb.Read(fl, 0, bb.Count)
 bb.Reverse()
  
 i = Int@(bb.Data)
  
 Print i
  
 fl.Close
  
End

oppure:

Public Sub Main()

 Dim fl As File
 Dim bb As New Byte[3]
 Dim i As Integer
 
 fl = Open "/percorso/del/file" For Read
  
 bb.Read(fl, 0, bb.Count)
  
 fl.Close
 i = bb[2]
 i += bb[1] * 256            ' &0100
 i += bb[0] * 65536        ' &010000
  
 Print i
  
End

oppure:

Public Sub Main()
 
 Dim fl As File
 Dim bb As New Byte[3]
 Dim i As Integer
  
 fl = Open "/percorso/del/file" For Read
  
 bb.Read(fl, 0, bb.Count)
  
 fl.Close
 
 i = (bb[2] Or ((bb[1] * CInt(2 ^ 8)))) Or (bb[0] * CInt(2 ^ 16))
  
' oppure anche così:
'     (bb[2] Or (Shl(CInt(bb[1]), 8))) Or Shl(CInt(bb[0]), 16)
   
 Print i
  
End

oppure usando le risorse stringa con successiva conversione in valore numerico

Public Sub Main()

 Dim fl As File
 Dim bb As New Byte[3]
 Dim s As String
 Dim i As Integer
  
 fl = Open "/percorso/del/file" For Read
  
 bb.Read(fl, 0, bb.Count)
  
 fl.Close
  
 s = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
  
 i = Val("&" & s)
   
 Print i
  
End


Note

[1] Questa soluzione è stata proposta da Top Fuel, membro del forum www.gambas-it.org