11111010111 1010 1011

Programar por Programar


¿Te gusta programar?
Inicio


Código fuente de BigFrac.vb

Estructura en Visual Basic 2005 que usa BigNum_ltm.dll y BigNum.vb


Publicado: 22/Oct/2007
Actualizado: 22/oct/2007
Autor: Guillermo 'guille' Som


 

Este es el código fuente de BigFrac, esta estructura usa BigNum para hacer los cálculos y demás cosas que "intenta" hacer.


Código fuente de BigFrac
'------------------------------------------------------------------------------
' BigFrac                                                           (19/Oct/07)
' Estructura basada en BigNum para números fraccionarios
' al estilo de 1/3, 555/23, etc.
'
' ©Guillermo 'guille' Som, 2007
'
' Para usarlos definirlos como:
' Dim df As New BigFrac(entero, fraccion)
' Por ejemplo, la fracción 1/5 se definiría como:
' Dim df As New BigFrac(1, 5)
'
' Esta clase está basada en el código de Java publicado en:
' http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/estatico/fraccion/fraccion.htm
'------------------------------------------------------------------------------
Option Strict On

Imports Microsoft.VisualBasic
Imports System

Imports System.Text

''' <summary>
''' Estructura para usar números fraccionarios de gran precisión
''' al estilo de 10/4
''' </summary>
''' <remarks>
''' Iniciado: 19/Oct/2007
''' Revisado: 22/Oct/2007
''' </remarks>
Public Structure BigFrac
    Implements IComparable

    ''' <summary>
    ''' Para la interfaz IComparable
    ''' </summary>
    ''' <param name="obj"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CompareTo(ByVal obj As Object) As Integer _
                Implements System.IComparable.CompareTo
        If TypeOf obj Is BigFrac Then
            Dim bf As BigFrac = obj.ToString
            Return Compare(Me, bf)
        Else
            'Return String.Compare(Me.ToString, obj.ToString)
            Return 0
        End If
    End Function

    ''' <summary>
    ''' La parte entera (numerador)
    ''' </summary>
    ''' <remarks></remarks>
    Public entero As BigNum
    ''' <summary>
    ''' La parte fraccionaria (denominador)
    ''' </summary>
    ''' <remarks></remarks>
    Public fraccion As BigNum

    ''' <summary>
    ''' Crea un nuevo objeto a partir de dos BigNum
    ''' Debido a que BigNum permite crear objetos desde
    ''' una cadena o cualquier tipo numérico, 
    ''' en este constructor también se admiten esos tipos
    ''' como argumentos del constructor
    ''' </summary>
    ''' <param name="entero">
    ''' La parte entera (numerador)
    ''' </param>
    ''' <param name="fraccion">
    ''' La fracción (denominador)
    ''' </param>
    ''' <remarks></remarks>
    Public Sub New(ByVal entero As BigNum, ByVal fraccion As BigNum)
        Me.entero = entero
        Me.fraccion = fraccion
        If SimplificarOperaciones Then
            Dim bf As BigFrac = Simplificar(Me)
            Me.entero = bf.entero
            Me.fraccion = bf.fraccion
        End If
    End Sub

    ''' <summary>
    ''' Crea un objeto a partir de una cadena
    ''' La cadena tendrá el formato n1 / n2
    ''' aunque también puede ser sin /
    ''' Se pueden usar números con decimales
    ''' por ejemplo: 7.3 se interpreta como 73/10
    ''' En otros casos si se simplifican quedarán cosas como
    ''' 10.5 -> 21/2 en vez de 105/10
    ''' </summary>
    ''' <param name="num"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal num As String)
        Dim bf As BigFrac
        If SimplificarOperaciones Then
            bf = Simplificar(Parse(num))
        Else
            bf = Parse(num)
        End If
        Me.entero = bf.entero
        Me.fraccion = bf.fraccion
    End Sub

    ''' <summary>
    ''' Crea un objeto a partir de un Double
    ''' </summary>
    ''' <param name="num"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal num As Double)
        Dim bf As BigFrac
        If SimplificarOperaciones Then
            bf = Simplificar(Parse(num))
        Else
            bf = Parse(num)
        End If
        Me.entero = bf.entero
        Me.fraccion = bf.fraccion
    End Sub

    ''' <summary>
    ''' Devuelve el valor como una cadena
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function ToString() As String
        ' No devolver la fracción si es cero o 1
        If BigNum.IsZero(fraccion) OrElse fraccion = BigNum.One Then
            Return entero
        End If
        Return entero & "/" & fraccion
    End Function


    ' TODO: No se si se deben simplificar los resultados
    ' Lo dejo a elección del usuario
    ' por defecto se simplifican
    ' que es como debe ser.

    ''' <summary>
    ''' Para simplificar los resultados de las operaciones aritméticas
    ''' </summary>
    ''' <remarks>
    ''' Por defecto es True
    ''' </remarks>
    Public Shared SimplificarOperaciones As Boolean = True ' False

    ''' <summary>
    ''' Simplificar las operaciones de comparación
    ''' </summary>
    ''' <remarks>
    ''' Por defecto es True
    ''' ya que 20/10 es lo mismo que 10/5
    ''' </remarks>
    Public Shared SimplificarOperacionesComparacion As Boolean = True

    ''' <summary>
    ''' Suma dos números
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Sum(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Dim c As BigFrac
        c.entero = a.entero * b.fraccion + b.entero * a.fraccion
        c.fraccion = a.fraccion * b.fraccion

        If SimplificarOperaciones Then
            Return Simplificar(c)
        Else
            Return c
        End If
    End Function

    ''' <summary>
    ''' Suma dos números
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Add(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Return Sum(a, b)
    End Function

    ''' <summary>
    ''' Resta dos números
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function [Sub](ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Dim c As BigFrac
        c.entero = a.entero * b.fraccion - b.entero * a.fraccion
        c.fraccion = a.fraccion * b.fraccion

        If SimplificarOperaciones Then
            Return Simplificar(c)
        Else
            Return c
        End If
    End Function

    ''' <summary>
    ''' Multiplica dos números
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Mul(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Return New BigFrac(a.entero * b.entero, a.fraccion * b.fraccion)
    End Function

    ''' <summary>
    ''' Divide dos números
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Div(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Return New BigFrac(a.entero * b.fraccion, a.fraccion * b.entero)
    End Function

    ''' <summary>
    ''' Devuelve el resto de la división
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function DivMod(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Return BigFrac.Mod(a, b)
    End Function

    ''' <summary>
    ''' División entera
    ''' </summary>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function DivInt(ByVal a As BigFrac, ByVal b As BigFrac) As BigFrac
        Return Parse(Div(a, b).entero)
    End Function


    ''' <summary>
    ''' Número máximo de decimales a mostrar en las fracciones
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Property MaxDecimales() As Integer
        Get
            Return BigFloat.MaxDecimales
        End Get
        Set(ByVal value As Integer)
            BigFloat.MaxDecimales = value
        End Set
    End Property


    ' La función inversa, recibe una fracción como argumento
    ' y devuelve una fracción cuyo numerador es el denominador
    ' y cuyo denominador es el numerador de dicha fracción

    ''' <summary>
    ''' Devuelve la inversa del objeto actual
    ''' (invierte los valores en esta instancia)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Inversa(ByVal a As BigFrac) As BigFrac
        Return New BigFrac(a.fraccion, a.entero)
    End Function

    ''' <summary>
    ''' Devuelve la inversa del objeto actual
    ''' (invierte los valores en esta instancia)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Inversa() As BigFrac
        Swap(Me.entero, Me.fraccion)
    End Function

    ''' <summary>
    ''' Intercambia los valores pasados por referencia
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <param name="a"></param>
    ''' <param name="b"></param>
    ''' <remarks></remarks>
    Public Shared Sub Swap(Of T)(ByRef a As T, ByRef b As T)
        Dim c As T = b
        b = a
        a = c
    End Sub

    ' Para simplificar una fracción primero hay que hallar el máximo común divisor
    ' del numerador y del denominador y dividirlos por ese valor,
    ' de esta forma se reduce a la fracción equivalente más simple

    ''' <summary>
    ''' Reducir la fracción al equivalente más simple
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Simplificar() As BigFrac
        Dim bf As BigFrac = Simplificar(Me)
        Me.entero = bf.entero
        Me.fraccion = bf.fraccion

        Return Me
    End Function

    ''' <summary>
    ''' Reducir la fracción al equivalente más simple
    ''' </summary>
    ''' <param name="bf"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Simplificar(ByVal bf As BigFrac) As BigFrac
        Dim d As BigNum = BigNum.BigNumMCD(bf.entero, bf.fraccion)

        'Console.WriteLine("{3} --> MCD({0}, {1}) = {2}", bf.entero, bf.fraccion, d, bf)
        ''Console.WriteLine("{0} <==> {1}", bf.entero, bf.fraccion)

        bf.entero = bf.entero / d
        bf.fraccion = bf.fraccion / d
        'Console.WriteLine("{0} <**> {1}", bf.entero, bf.fraccion)

        ' Si es n / n asignar 1
        ' si es 0 / n asignar 0
        Dim i As Integer = BigNum.Compare(bf.entero, bf.fraccion)
        If i = 0 Then
            bf.entero = BigNum.One
            bf.fraccion = BigNum.One ' BigNum.Zero
        Else
            If BigNum.IsZero(bf.entero) Then
                bf.entero = BigNum.Zero
                bf.fraccion = BigNum.One ' BigNum.Zero
            End If
        End If

        Return bf
    End Function

    '
    ' Los métodos que he definido en BigFrac de BigInt_lib
    '


    ''' <summary>
    ''' Devuelve True si es negativo
    ''' El cero no es ni positivo ni negativo
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Negative(ByVal num As BigFrac) As Boolean
        Return num < 0
    End Function

    ''' <summary>
    ''' Devuelve True si es positivo
    ''' El cero no es ni positivo ni negativo
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Positive(ByVal num As BigFrac) As Boolean
        Return num > 0
    End Function

    ''' <summary>
    ''' Eleva el número a la potencia indicada
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Powi(ByVal num1 As BigFrac, ByVal num2 As Integer) As BigFrac
        If num2 = 2 Then Return Pow2(num1)

        Dim bf1 As BigFloat = num1
        Dim bf2 As BigFloat = num2
        Return bf1 ^ bf2
    End Function

    ''' <summary>
    ''' Eleva el número a la potencia indicada
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Pow(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As BigFrac
        If num2 = 2 Then Return Pow2(num1)

        Dim bf1 As BigFloat = num1
        Dim bf2 As BigFloat = num2
        Return bf1 ^ bf2
    End Function

    ''' <summary>
    ''' Devuelve el número al cuadrado
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Pow2(ByVal num1 As BigFrac) As BigFrac
        Return num1 * num1
    End Function

    ''' <summary>
    ''' Devuelve -1 si es negativo, 1 si es positivo
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Sign(ByVal num As BigFrac) As Integer
        If Equal(num, BigFrac.Zero) Then
            Return 0
        ElseIf num > Zero Then
            Return 1
        Else
            Return -1
        End If
    End Function

    ''' <summary>
    ''' Devuelve 1
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property One() As BigFrac
        Get
            Return "1"
        End Get
    End Property

    ''' <summary>
    ''' Devuelve cero
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property Zero() As BigFrac
        Get
            Return "0"
        End Get
    End Property

    ''' <summary>
    ''' Devuelve True si el BigFloat indicado es cero
    ''' </summary>
    ''' <param name="n1"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function IsZero(ByVal n1 As BigFrac) As Boolean
        Return Equal(n1, BigFrac.Zero)
    End Function

    ''' <summary>
    ''' Devuelve True si este número es cero
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsZero() As Boolean
        Return Equal(Me, BigFrac.Zero)
    End Function



    ''' <summary>
    ''' Devuelve el mayor de los dos
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Max(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As BigFrac
        Return BigFloat.Max(num1, num2)
    End Function

    ''' <summary>
    ''' Devuelve el menor de los dos
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Min(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As BigFrac
        Return BigFloat.Min(num1, num2)
    End Function

    ''' <summary>
    ''' Devuelve el resto de la división
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function [Mod](ByVal num1 As BigFrac, ByVal num2 As BigFrac) As BigFrac
        Dim bfl1 As BigFloat = num1
        Dim bfl2 As BigFloat = num2

        Return bfl1 Mod bfl2
    End Function


    ''' <summary>
    ''' El valor de PI
    ''' (se devuelve el valor definido en BigFloat)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property PI() As BigFrac
        Get
            Return Parse(BigFloat.PI)
        End Get
    End Property

    ''' <summary>
    ''' El valor de E
    ''' (se devuelve el valor definido en BigFloat)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property E() As BigFrac
        Get
            Return Parse(BigFloat.E)
        End Get
    End Property


    ''' <summary>
    ''' Devuelve el mayor de la lista indicada
    ''' </summary>
    ''' <param name="parametros"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Max(ByVal ParamArray parametros() As BigFrac) As BigFrac
        Array.Sort(parametros)
        Return parametros(parametros.Length - 1)
    End Function

    ''' <summary>
    ''' Devuelve el menor de la lista indicada
    ''' </summary>
    ''' <param name="parametros"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Min(ByVal ParamArray parametros() As BigFrac) As BigFrac
        Array.Sort(parametros)
        Return parametros(0)
    End Function


    ''' <summary>
    ''' Devuelve la suma de todos los valores indicados
    ''' </summary>
    ''' <param name="parametros"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Suma(ByVal ParamArray parametros() As BigFrac) As BigFrac
        Dim t As BigFrac = parametros(0)
        For i As Integer = 1 To parametros.Length - 1
            t = t + parametros(i)
        Next
        Return t
    End Function

    ''' <summary>
    ''' Suma el contenido de un array con otros valores
    ''' </summary>
    ''' <param name="numeros"></param>
    ''' <param name="parametros"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Suma(ByVal numeros() As BigFrac, _
                                ByVal ParamArray parametros() As BigFrac) As BigFrac
        Dim t As BigFrac = parametros(0)
        For i As Integer = 1 To parametros.Length - 1
            t = t + parametros(i)
        Next
        For i As Integer = 0 To numeros.Length - 1
            t = t + numeros(i)
        Next
        Return t
    End Function

    ''' <summary>
    ''' Devuelve la media aritmética de los números indicados
    ''' El valor devuelto es de tipo BigFrac
    ''' </summary>
    ''' <param name="parametros"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Media(ByVal ParamArray parametros() As BigFrac) As BigFrac
        Dim t As BigFrac = Suma(parametros)
        Return t \ parametros.Length
    End Function

    ''' <summary>
    ''' Devuelve la media del total y la cantidad indicadas
    ''' Esto es válido para calcular primero con Suma
    ''' </summary>
    ''' <param name="total"></param>
    ''' <param name="cant"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Media(ByVal total As BigFrac, ByVal cant As BigFrac) As BigFrac
        Return total \ cant
    End Function

    ''' <summary>
    ''' Devuelve el porcentaje del primero número sobre el segundo:
    ''' num1 * num2 / 100
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Porcentaje(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As BigFrac
        Return num1 * num2 / 100
    End Function


    ''' <summary>
    ''' Devuelve el valor absoluto
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Abs(ByVal num As BigFrac) As BigFrac
        Return BigNum.BigNumAbs(num.entero)
    End Function

    ''' <summary>
    ''' Compara dos números
    ''' Devuelve 0 si son iguales
    ''' 1 si el primero es mayor
    ''' -1 si el primero es menor
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Compare(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Integer
        Dim i As Integer = 0

        If SimplificarOperacionesComparacion Then
            num1 = Simplificar(num1)
            num2 = Simplificar(num2)
        End If
        If num1.entero = num2.entero AndAlso num1.fraccion = num2.fraccion Then
            i = 0
        ElseIf num1.entero < num2.entero OrElse num1.fraccion < num2.fraccion Then
            i = -1
        Else
            i = 1
        End If

        Return i
    End Function


    ''' <summary>
    ''' Devuelve True si son iguales
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Equal(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Boolean
        Return Compare(num1, num2) = 0
    End Function

    ''' <summary>
    ''' Devuelve True si el primero es mayor
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GT(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Boolean
        Return Compare(num1, num2) = 1
    End Function

    ''' <summary>
    ''' Devuelve True si el primero es mayor o igual
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GTE(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Boolean
        Return Compare(num1, num2) <> -1
    End Function

    ''' <summary>
    ''' Devuelve True si el primero es menor
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function LT(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Boolean
        Return Compare(num1, num2) = -1
    End Function

    ''' <summary>
    ''' Devuelve True si el primero es menor o igual
    ''' </summary>
    ''' <param name="num1"></param>
    ''' <param name="num2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function LTE(ByVal num1 As BigFrac, ByVal num2 As BigFrac) As Boolean
        Return Compare(num1, num2) <> 1
    End Function




    ''' <summary>
    ''' Convierte una cadena en una fracción
    ''' El formato será numerador / denominador
    ''' Si no se indica el denominador será 1
    ''' Se pueden usar números con decimales
    ''' por ejemplo: 7.3 se interpreta como 73/10
    ''' En otros casos si se simplifican quedarán cosas como
    ''' 10.5 -> 21/2 en vez de 105/10
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal num As String) As BigFrac
        Dim i As Integer
        Dim ent As BigNum
        Dim frac As BigNum

        ' Si tiene decimales .5 se multiplica por 2
        ' y se devuelve el resultado y la fracción
        ' En otro caso, se cambia el punto por /
        i = num.IndexOfAny(".,".ToCharArray)
        If i > -1 Then
            Dim sDec As String = num.Substring(i + 1)
            Dim bf1 As BigFloat = "1" & New String("0"c, Len(sDec))
            Dim bf2 As BigNum = BigFloat.Parse(num) * bf1
            ent = BigFloat.ToBigNum(bf2)
            frac = BigFloat.ToBigNum(bf1)
            Return New BigFrac(ent, frac)
        End If
        i = num.IndexOf("/")
        If i = -1 Then
            Return New BigFrac(num, 1)
        End If
        ent = num.Substring(0, i).Trim
        frac = num.Substring(i + 1).Trim

        Return New BigFrac(ent, frac)
    End Function

    ''' <summary>
    ''' Convierte un Double en un BigFrac
    ''' Se convierte a cadena y se evalúa en Parse(string)
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal num As Double) As BigFrac
        Return Parse(num.ToString)
    End Function

    ''' <summary>
    ''' Convierte un BigFloat en BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal num As BigFloat) As BigFrac
        Return Parse(num.ToString)
    End Function

    ''' <summary>
    ''' Convierte un BigFrac en BigFloat
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToBigFloat(ByVal num As BigFrac) As BigFloat
        Return CType(num.entero, BigFloat) / CType(num.fraccion, BigFloat)
    End Function

    ''' <summary>
    ''' Convierte un BigFrac en un BigNum
    ''' Devuelve solo la parte entera
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToBigNum(ByVal num As BigFrac) As BigNum
        Return num.entero
    End Function

    ''' <summary>
    ''' Convierte un BigNum en un BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal num As BigNum) As BigFrac
        Return New BigFrac(num, 1)
    End Function


    '
    ' Conversiones
    '

    Public Shared Widening Operator CType(ByVal num As String) As BigFrac
        Return Parse(num)
    End Operator

    Public Shared Widening Operator CType(ByVal num As Double) As BigFrac
        Return Parse(num)
    End Operator

    Public Shared Widening Operator CType(ByVal num As BigFrac) As String
        Return num.ToString
    End Operator

    ''' <summary>
    ''' Convierte de BigFrac a BigFloat
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigFrac) As BigFloat
        Return ToBigFloat(num)
    End Operator

    ''' <summary>
    ''' Convierte un BigFloat en BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigFloat) As BigFrac
        Return Parse(num)
    End Operator

    ''' <summary>
    ''' Convierte un BigFrac en BigNum
    ''' Devuelve solo la parte entera
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigFrac) As BigNum
        Return ToBigNum(num)
    End Operator

    ''' <summary>
    ''' Convierte un BigNum en BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigNum) As BigFrac
        Return Parse(num)
    End Operator




    '
    ' Sobrecarga de operadores
    '

    ''' <summary>
    ''' Operador unario, devuelve el mismo número
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator +(ByVal bf1 As BigFrac) As BigFrac
        Return bf1
    End Operator

    ''' <summary>
    ''' Operador unario, devuelve el número negado
    ''' Será negativo si era positivo y viceversa
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator -(ByVal bf1 As BigFrac) As BigFrac
        Return Mul(bf1, -1)
    End Operator

    ''' <summary>
    ''' Devuelve la suma de los dos números
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator +(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return Sum(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve la resta de los dos números
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator -(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return [Sub](bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve la multiplicación de los dos números
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator *(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return Mul(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve la división de los dos números
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator /(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return Div(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve la división de los dos números
    ''' (devuelve solo la parte entera)
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator \(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return Parse(Div(bf1, bf2).entero)
    End Operator

    ''' <summary>
    ''' Devuelve el número elevado a la potencia indicada
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator ^(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return Pow(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve el resto de la división
    ''' </summary>
    ''' <param name="bf1"></param>
    ''' <param name="bf2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Operator Mod(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As BigFrac
        Return BigFrac.Mod(bf1, bf2)
    End Operator


    '
    ' Operadores de comparación
    '

    ' En las comparaciones se debería simplificar siempre
    ' ya que 10/5 es igual a 20/10

    Public Shared Operator =(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) = 0
    End Operator

    Public Shared Operator <>(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) <> 0
    End Operator

    Public Shared Operator <(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) = -1
    End Operator

    Public Shared Operator >(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) = 1
    End Operator

    Public Shared Operator <=(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) <> 1
    End Operator

    Public Shared Operator >=(ByVal bf1 As BigFrac, ByVal bf2 As BigFrac) As Boolean
        Return Compare(bf1, bf2) <> -1
    End Operator


    '
    ' Sobrecarga de operadores booleanos
    '

    Public Shared Operator IsTrue(ByVal bn As BigFrac) As Boolean
        'Return Compare(bn, 0) <> 0
        If SimplificarOperacionesComparacion Then
            bn = Simplificar(bn)
        End If

        Return Not (bn.entero.IsZero AndAlso bn.fraccion.IsZero)
    End Operator

    Public Shared Operator IsFalse(ByVal bn As BigFrac) As Boolean
        If SimplificarOperacionesComparacion Then
            bn = Simplificar(bn)
        End If

        Return (bn.entero.IsZero AndAlso bn.fraccion.IsZero)
    End Operator


End Structure


Programar por programar... ¡porque te gusta programar!
Ir al índice principal
Ir al sitio del Guille - Ir a los foros del Guille

Has entrado usando el host www.programarporprogramar.org