Condividi tramite


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: