VB.NET: Calcolare una frazione (it-IT)
Obiettivo
In questo breve articolo, vedremo un metodo semplice per convertire la parte decimale di un numero nella sua rappresentazione frazionale, sviluppando una classe utile a questo fine. Per l'obiettivo prefissato, utilizzeremo Visual Basic .NET.
Calcolare e semplificare una frazione
Per calcolare una frazione, separeremo la parte intera di un numero da quella decimale, per lavorare quindi su quest'ultima in termini di numeratore e denominatore. Prendiamo ad esempio il numero 12.65. Lo esprimeremo per prima cosa come 12 + 0.65, procedendo poi a scriverne la parte decimale come la più ampia frazione non semplificata possibile. Dal momento che abbiamo due cifre decimali dopo la virgola, il denominatore più grande di cui abbisogniamo sarà 100. Di conseguenza, possiamo esprimere il valore di 0.65 come 65/100. Poi, utilizzando le regole comuni relative al Massimo Comun Divisore (MCD, qui indicato come GDC dall'inglese Greatest Common Divisor), possiamo semplificare la nostra frazione portandola al risultato di 13/20.
Trovare il Massimo Comun Divisore
Segue un semplice scorcio di codice che aiuta nel trovare il GCD tra due numeri:
Private Function gcd(ByVal n1 As Integer, ByVal n2 As Integer) As Long
Dim minimum As Long
If n1 < n2 Then
minimum = n1
Else
minimum = n2
End If
For i As Long = minimum To 1 Step -1
If n1 Mod i = 0 And n2 Mod i = 0 Then
Return i
End If
Next
End Function
Calcolare una frazione
Segue la routine utile al calcolo della nostra frazione: necessita di un parametro di input di tipo Decimal (come il valore di 12.65 usato sopra)
Public Function Calculate(value As Decimal) As String
Dim intPart As Long = Math.Truncate(value)
Dim numerator As Long = CType((value - intPart).ToString.Substring(2), Long)
Dim denominator As Long = CType("1" & StrDup(numerator.ToString.Length, "0"), Long)
Dim _gcd As Long = gcd(numerator, denominator)
Dim nDiv As Long = _gcd
While nDiv > 1
If numerator Mod nDiv = 0 And denominator Mod nDiv = 0 Then
numerator /= nDiv
denominator /= nDiv
nDiv = _gcd
Else
nDiv -= 1
End If
End While
Dim retVal As String = ""
If intPart > 0 Then retVal = intPart.ToString & " + ("
retVal &= numerator.ToString + " / " + denominator.ToString
If intPart > 0 Then retVal &= ")"
Return retVal
End Function
La funzione salva la parte intera del numero per un uso futuro, e procede a calcolare il massimo denominatore necessario, aggiungendo alla cifra 1 un numero di zeri pari a quello delle cifre decimali del valore di origine. Una chiamata alla funzione per il calcolo del GCD ci permetterà di verificare il divisore di partenza, dopodichè si entrerà in un ciclo nel quale procederemo alla divisione del numeratore e denominatore rispetto ai divisori comuni, fino a che non vi saranno ulteriori divisori possibili.
Infine, avendo determinato la frazione semplificata in termini di numeratore e denominatore, la routine produrrà una rappresentazione di tipo String del risultato, aggiungendovi la parte intera. Quindi, rispetto all'esempio precedente, dove value = 12.65, il risultato sarà: 12 + (13/20).
Come il lettore può notare dal codice, nel caso non vi sia parte intera la frazione risultante sarà espressa senza parentesi.
Classe Fraction
Il codice completo per una classe Fraction riutilizzabile può essere reso come segue:
Public Class Fraction
Dim _value As Decimal
Dim _fraction As String
Public ReadOnly Property Value As String
Get
Return _fraction
End Get
End Property
Public Property Number As Decimal
Get
Return _value
End Get
Set(value As Decimal)
_value = value
_fraction = Calculate(_value)
End Set
End Property
Public Sub New(value As Decimal)
_value = value
_fraction = Calculate(_value)
End Sub
Public Sub New()
_value = 0
_fraction = 0
End Sub
Private Function gcd(ByVal n1 As Integer, ByVal n2 As Integer) As Long
Dim minimum As Long
If n1 < n2 Then
minimum = n1
Else
minimum = n2
End If
For i As Long = minimum To 1 Step -1
If n1 Mod i = 0 And n2 Mod i = 0 Then
Return i
End If
Next
End Function
Public Function Calculate(value As Decimal) As String
Dim intPart As Long = Math.Truncate(value)
Dim numerator As Long = CType((value - intPart).ToString.Substring(2), Long)
Dim denominator As Long = CType("1" & StrDup(numerator.ToString.Length, "0"), Long)
Dim _gcd As Long = gcd(numerator, denominator)
Dim nDiv As Long = _gcd
While nDiv > 1
If numerator Mod nDiv = 0 And denominator Mod nDiv = 0 Then
numerator /= nDiv
denominator /= nDiv
nDiv = _gcd
Else
nDiv -= 1
End If
End While
Dim retVal As String = ""
If intPart > 0 Then retVal = intPart.ToString & " + ("
retVal &= numerator.ToString + " / " + denominator.ToString
If intPart > 0 Then retVal &= ")"
Return retVal
End Function
End Class
Nel codice sorgente allegato a questo articolo, ho implementato un semplice WinForm, con un TextBox ed alcune Labels, per mostrare il funzionamento di quanto sopra.
Il code behind sarà molto semplicemente il seguente:
Public Class Form1
Dim f As New Fraction
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
f.Number = CType(TextBox1.Text, Decimal)
Label3.Text = f.Value
End Sub
End Class
Quando viene premuto il tasto Button, la proprietà Number della nostra classe Fraction verrà inizializzata tramite un cast verso Decimal di quanto digitato nel TextBox1.
Successivamente, la proprietà Value (che contiene il numero di partenza espresso come frazione) sarà mostrato nella Label3.
Codice sorgente
Il codice sorgente utilizzato in questo articolo può essere scaricato al seguente link: https://code.msdn.microsoft.com/Calculate-Fractions-in-75d539e7
Altre lingue
Il presente articolo è disponibile nelle seguenti localizzazioni:
- [en-US] Calculate Fractions in VB.NET