11111010111 1010 1011

Programar por Programar


¿Te gusta programar?
Inicio


El código fuente de la estructura BigFrac


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


 

Pues eso... el código fuente de la estructura BigFrac.


El código de BigFrac
'------------------------------------------------------------------------------
' BigFloat                                                          (20/Oct/07)
' Estructura basada en BigInt para números fraccionarios
' al estilo de 1/3, 555/23, etc.
'
' Estructura basada en BigInt de F#
' Se necesita una referencia a fslib.dll
'
' Se debe configurar para que no haya overflow en números enteros
'
' El espacio de nombres de esta librería es:
' elGuille.Developer.FSharp
'
' ©Guillermo 'guille' Som, 2007
'------------------------------------------------------------------------------
Option Strict On

Imports Microsoft.VisualBasic
Imports System

Imports System.Text

Imports fsm = Microsoft.FSharp.Math
Imports fsbnm = Microsoft.FSharp.Math.BigNumModule

''' <summary>
''' Estructura para manejar números fraccionarios
''' de gran precisión
''' al estilo de 10/4
''' </summary>
''' <remarks>
''' Iniciado: 20/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 BigInt
    ''' <summary>
    ''' La parte fraccionaria (denominador)
    ''' </summary>
    ''' <remarks></remarks>
    Public fraccion As BigInt


    ''' <summary>
    ''' Crea un nuevo objeto a partir de dos BigInt
    ''' Debido a que BigInt 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 BigInt, ByVal fraccion As BigInt)
        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
    ''' El signo / solo se muestra si el denominador (fracción)
    ''' no es ni cero ni uno
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function ToString() As String
        ' No devolver la fracción si es cero o 1
        If BigInt.IsZero(fraccion) OrElse BigInt.IsOne(fraccion) 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 no se simplifican
    ' aunque solo se hará en las sobrecargas???

    ''' <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 fracciones
    ''' </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
        Return fsbnm.add(a, b)
        '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 fracciones
    ''' </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 fsbnm.add(a, b)
        'Return Sum(a, b)
    End Function

    ''' <summary>
    ''' Resta dos fracciones
    ''' </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
        Return fsbnm.sub(a, b)

        '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 fracciones
    ''' </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 fsbnm.mul(a, b)
        'Return New BigFrac(a.entero * b.entero, a.fraccion * b.fraccion)
    End Function

    ''' <summary>
    ''' Divide dos fracciones
    ''' </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 fsbnm.div(a, b)
        '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 BigInt.MaxDecimales
        End Get
        Set(ByVal value As Integer)
            BigInt.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
    ''' </summary>
    ''' <param name="a"></param>
    ''' <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)
        Return Me
    End Function

    ''' <summary>
    ''' Intercambia los valores de las dos variables pasadas 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 BigInt = BigInt.MCD(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 = BigInt.Compare(bf.entero, bf.fraccion)
        If i = 0 Then
            bf.entero = BigInt.One
            bf.fraccion = BigInt.One ' BigInt.Zero
        Else
            If BigInt.IsZero(bf.entero) Then
                bf.entero = BigInt.Zero
                bf.fraccion = BigInt.One ' BigInt.Zero
            End If
        End If

        Return bf
    End Function


    '
    ' Estos métodos son los de BigNumModule de F#
    '

    ''' <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 fsbnm.abs(num)
    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
        Return fsbnm.compare(num1, num2)
    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 fsbnm.equal(num1, num2)
    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 fsbnm.gt(num1, num2)
    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 fsbnm.gte(num1, num2)
    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 fsbnm.lt(num1, num2)
    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 fsbnm.lte(num1, num2)
    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 fsbnm.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 fsbnm.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>
    ''' Devuelve el valor negado
    ''' Si era negativo, lo devuelve como positivo
    ''' y viceversa
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Neg(ByVal num As BigFrac) As BigFrac
        Return fsbnm.neg(num)
    End Function

    ''' <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 fsbnm.negative(num)
    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 fsbnm.positive(num)
    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
        Return fsbnm.powi(num1, num2)
    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
        Return fsbnm.sign(num)
    End Function

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

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


    '
    ' Estos métodos y propiedades no están en la clase BigNum de F#
    '

    ''' <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



    '
    ' El método Parse para realizar distintas conversiones
    '


    ''' <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 BigInt
        Dim frac As BigInt

        ' 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 BigInt = BigFloat.Parse(num) * bf1
            ent = BigFloat.ToBigInt(bf2)
            frac = BigFloat.ToBigInt(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)
        'Dim d1 As Double = Fix(num)

        'Return New BigFrac(d1, 1)
    End Function

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

    ''' <summary>
    ''' Convierte un BigNum de F# en un BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal num As fsm.BigNum) As BigFrac
        Dim s As String = fsbnm.to_string(num)
        Return Parse(s)
    End Function

    '''' <summary>
    '''' Convierte un BigFrac en un BigNum de F#
    '''' </summary>
    '''' <param name="num"></param>
    '''' <returns></returns>
    '''' <remarks></remarks>
    'Public Shared Function Parse(ByVal num As BigFrac) As fsm.BigNum
    '    Return fsbnm.of_string(num.ToString)
    'End Function

    ''' <summary>
    ''' Convierte un BigFrac en un BigNum de F#
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToFSharpBigNum(ByVal num As BigFrac) As fsm.BigNum
        Return fsbnm.of_string(num.ToString)
    End Function

    ''' <summary>
    ''' Convierte un BigFrac en un BigInt
    ''' Devuelve solo la parte entera
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToBigInt(ByVal num As BigFrac) As BigInt
        Return num.entero
    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



    '
    ' Conversiones
    '

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

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

    ''' <summary>
    ''' Convierte un BigFrac en una cadena
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigFrac) As String
        Return num.ToString
    End Operator

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

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

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

    ''' <summary>
    ''' Convierte un BigInt en BigFrac
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Widening Operator CType(ByVal num As BigInt) As BigFrac
        Return Parse(num)
    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


    '
    ' 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 Neg(bf1)
    End Operator


    ''' <summary>
    ''' Suma dos BigFrac
    ''' </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>
    ''' Resta dos BigFrac
    ''' </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>
    ''' Multiplica dos BigFrac
    ''' </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>
    ''' Divide dos BigFrac
    ''' </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>
    ''' Divide dos BigFrac
    ''' (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

    ''' <summary>
    ''' Devuelve True si son iguales
    ''' </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 Boolean
        Return Equal(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve True si son distintos
    ''' </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 Boolean
        Return Equal(bf1, bf2) = False
    End Operator

    ''' <summary>
    ''' Devuelve True si el primero es menor
    ''' </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 Boolean
        Return LT(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve True si el primero es mayor
    ''' </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 Boolean
        Return GT(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve True si el primero es menor o igual
    ''' </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 Boolean
        Return LTE(bf1, bf2)
    End Operator

    ''' <summary>
    ''' Devuelve True si el primero es mayor o igual
    ''' </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 Boolean
        Return GTE(bf1, bf2)
    End Operator

    '
    ' Sobrecarga de operadores booleanos
    '

    ''' <summary>
    ''' Devuelve True si no es cero
    ''' </summary>
    ''' <param name="bn"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' Si SimplificarOperacionesComparacion = False
    ''' seguramente no devolverá el valor correcto
    ''' </remarks>
    Public Shared Operator IsTrue(ByVal bn As BigFrac) As Boolean
        If SimplificarOperacionesComparacion Then
            bn = Simplificar(bn)
        End If

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

    ''' <summary>
    ''' Devuelve True si es cero
    ''' </summary>
    ''' <param name="bn"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' Si SimplificarOperacionesComparacion = False
    ''' seguramente no devolverá el valor correcto
    ''' </remarks>
    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