Come tutti i programmatori sanno, in informatica vengono utilizzate delle abbreviazioni per indicare l’unità di misura per la dimensione di un file, della RAM o di un hard disk: per esempio un file di 1.024 byte equivale a un file di 1 “kB”.
Le abbreviazioni utilizzate attualmente sono le seguenti:
- kiloByte –> kB –> 1.024 (circa 10^3)
- MegaByte –> MB –> 1.048.576 (circa 10^6)
- GigaByte –> GB –> 1.073.741.824 (circa 10^9)
- TeraByte –> TB –> 1.099.511.627.776 (circa 10^12)
- PetaByte –> PB –> 1.125.899.906.842.620 (circa 10^15)
- ExaByte –> EB –> 1.152.921.504.606.850.000 ( circa 10^18 )
- ZettaByte –> ZB –> 1,180.591.620.717.41E+21 (circa 10^21)
- YottaByte –> YB –> 1,208.925.819.614.63E+24 (circa 10^24)
Per noi programmatori potrebbe quindi essere utile avere una funzione in grado di abbreviare un numero molto grande, così da avere una rappresentazione molto più compatta. Il seguente codice fa proprio questo:
Module Module1
Public Function ConvertiByte( _
ByVal strNumero As String) As String
Dim risultato As String
Dim potenza As Integer = 0
Dim nByte As Decimal = 0
‘ verifico se è stato passato un parametro:
‘ se si, lo converto nel tipo Decimal
‘ se no, esco
‘TODO: aggiungere verifica se è un numero valido!
If strNumero <> “” Then
Try
nByte = CType(strNumero, Decimal)
Catch ex As Exception
Return “Numero troppo grande: Overflow”
End Try
Else
Return “Errore: nessun numero da valutare”
End If
‘ ciclo di riduzione del numero, estraendo
‘ il numero di iterazioni effettuate
Do While ((nByte / 1000) >= 1)
nByte = nByte / 1024
potenza += 1
Loop
‘ conversione in stringa con arrotondamento
risultato = Decimal.Round(nByte, 2).ToString
‘ aggiunta della giusta unità di misura
Select Case potenza
Case 0
risultato &= ” byte”
Case 1
risultato &= ” KB”
Case 2
risultato &= ” MB”
Case 3
risultato &= ” GB”
Case 4
risultato &= ” TB”
Case 5
risultato &= ” PB”
Case 6
risultato &= ” EB”
Case 7
risultato &= ” ZB”
Case 8
risultato &= ” YB”
Case Else
risultato = “Non valutabile”
End Select
Return risultato
End Function
End Module
A questo punto basta creare un form, aggiungere una casella di testo e un pulsante. Il codice per gestire l’evento Click del pulsante è il seguente:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(ConvertiByte(Me.TextBox1.Text))
End Sub
End Class
Semplice vero? Ma proviamo a migliorare un po’ la nostra funzione. E’ sufficiente sostituire tutto il codice seguente al commento “aggiunta della giusta unità di misura”:
‘ aggiunta della giusta unità di misura
Dim misure() As String = _
{“byte”, “KB”, “MB”, “GB”, “TB”, “PB”, “EB”, “ZB”, “YB”}
If potenza > 8 Then
risultato &= ” Non valutabile”
Else
risultato &= ” “ & misure(potenza)
End If
Return risultato
Con una semplice modifica, poi, possiamo fare in modo che la nostra funzione rappresenti un’abbreviazione di potenze di 10^3. Per esempio (i punti di separazione delle migliaia sono inseriti solo per chiarezza visiva):
- 1.000 –> 1 x 10^3
- 1.000.000 –> 1 x 10^6
- 55.555.555.555 –> 55,56 x 10^9
Ecco quindi la nostra funzione modificata:
Module Module1
Public Function ConvertiByte( _
ByVal strNumero As String) As String
Dim risultato As String
Dim potenza As Integer = 0
Dim nByte As Decimal = 0
‘ verifico se è stato passato un parametro:
‘ se si, lo converto nel tipo Decimal
‘ se no, esco
‘TODO: aggiungere verifica se è un numero valido!
If strNumero <> “” Then
Try
nByte = CType(strNumero, Decimal)
Catch ex As Exception
Return “Numero troppo grande: Overflow”
End Try
Else
Return “Errore: nessun numero da valutare”
End If
‘ ciclo di riduzione del numero, estraendo
‘ il numero di iterazioni effettuate
Do While ((nByte / 1000) >= 1)
nByte = nByte / 1000
potenza += 1
Loop
‘ conversione in stringa con arrotondamento
risultato = Decimal.Round(nByte, 2).ToString
‘ aggiunta della giusta unità di misura
risultato &= ” x 10^” & (potenza * 3).ToString
Return risultato
End Function
End Module
Come potete vedere, le uniche differenze sono date dal diverso divisore (1000 anziché 1024) e nella parte finale, dove viene composta la stringa che viene restituita dalla funzione al codice chiamante.
Una precisazione, prima che qualcuno possa pensare che si tratti di un errore. Il seguente codice:
Do While ((nByte / 1000) >= 1)
nByte = nByte / 1024
potenza += 1
Loop
potrebbe apparire strano o perfino sbagliato. Perché confronto la divisione per 1000 e poi divido per 1024?
E’ molto semplice: nel caso in cui, per esempio, volessi abbreviare 1000 byte, con il confronto per 1024 otterrei la non esecuzione dell’abbreviazione e quindi il risultato sarebbe “1000 byte” anziché “0,98 KB”. Di solito è abbastanza brutto veder superare il valore di 1000 in questi casi e quindi si preferisce comunque arrivare al massimo a 999 (confrontate per esempio con la visualizzazione dell’Esplora Risorse di Windows).
Una curiosità: notate come sia possibile, in VB.NET, scrivere una cosa del genere:
(potenza * 3).ToString
senza dover memorizzare il calcolo matematico in una variabile.
C’è ancora qualcuno che non è convinto a passare a VB.NET?