'------------------------------------------------------------------------------
' BigInt (19/Oct/07)
' 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 System.Reflection
Imports System.Diagnostics
Imports fsm = Microsoft.FSharp.Math
Imports fsc = Microsoft.FSharp.Core
' Alias para el tipo con las funciones
Imports fsbim = Microsoft.FSharp.Math.BigIntModule
''' <summary>
''' Estructura para manejar números enteros
''' de gran preción.
''' Internamente se usa el tipo BigInt de F#
''' Esta estructura es el tipo usado por
''' las otras estructuras de esta librería.
''' Necesita la librería fslib.dll de F#
''' y actualmente utiliza la versión 1.9.2.9
''' </summary>
''' <remarks>
''' Iniciado: 19/Oct/2007
''' Revisado: 22/Oct/2007
''' </remarks>
Public Structure BigInt
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
Return String.Compare(Me.ToString, obj.ToString)
End Function
Private m_Value As fsm.BigInt
''' <summary>
''' El valor del BigInt interno
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Value() As fsm.BigInt
Get
Return m_Value
End Get
Set(ByVal value As fsm.BigInt)
m_Value = value
End Set
End Property
'
' Métodos compartidos
'
''' <summary>
''' Suma dos BigInt
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Add(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.add(num1, num2)
End Function
''' <summary>
''' Valor absoluto del BigInt
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Abs(ByVal num1 As BigInt) As BigInt
Return fsbim.abs(num1)
End Function
''' <summary>
''' Compara dos BigInt
''' Devuelve 0 si son iguales
''' -1 si el primero es menor
''' 1 si el primero es mayor
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Compare(ByVal num1 As BigInt, ByVal num2 As BigInt) As Integer
Return fsbim.compare(num1.Value, num2.Value)
End Function
''' <summary>
''' Divide dos BigInt
''' Devuelve la parte entera
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Div(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.div(num1, num2)
End Function
''' <summary>
''' Devuelve el resto (módulo) de dividir los dos números indicados
''' La parte entera la devuelve por referencia en el tercer parámetro
''' En realidad es un num1 Mod num2 lo que se devuelve
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <param name="num3"></param>
''' <returns></returns>
''' <remarks>
''' Esta sobrecarga no tiene equivalente directo en F#
''' pero la dejo junto a los otros Div
''' </remarks>
Public Shared Function Div(ByVal num1 As BigInt, ByVal num2 As BigInt, _
ByRef num3 As BigInt) As BigInt
Dim bi3 As fsc.Tuple(Of fsm.BigInt, fsm.BigInt) = fsm.BigIntModule.divmod(num1, num2)
num3 = bi3.Item1
Return bi3.Item2
End Function
''' <summary>
''' Devuelve el resto (módulo) de dividir los dos números indicados
''' La parte entera la devuelve por referencia en el tercer parámetro
''' En realidad es un num1 Mod num2 lo que se devuelve
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <param name="num3"></param>
''' <returns></returns>
''' <remarks>
''' Esta sobrecarga no tiene equivalente directo en F#
''' pero la dejo junto a los otros Div
''' </remarks>
Public Shared Function DivRem(ByVal num1 As BigInt, ByVal num2 As BigInt, _
ByRef num3 As BigInt) As BigInt
Return Div(num1, num2, num3)
End Function
''' <summary>
''' Devuelve la división y el resto
''' El resto se devuelve y el valor entero se asigna al tercer parámetro
''' En realidad es un num1 Mod num2 lo que se devuelve
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <param name="num3"></param>
''' <returns></returns>
''' <remarks>
''' Hay que tener en cuenta (para los que no somos expertos en matemáticas)
''' que el resto en realidad es el resto de la división
''' no la parte fraccionaria:
''' Por ejemplo: 125 / 15 dará 8 y 5 en lugar de 8 y 0.3333333.
''' Esta sobrecarga no tiene equivalente directo en F#
''' </remarks>
Public Shared Function DivMod(ByVal num1 As BigInt, ByVal num2 As BigInt, _
ByRef num3 As BigInt) As BigInt
Dim bi3 As fsc.Tuple(Of fsm.BigInt, fsm.BigInt) = _
fsm.BigIntModule.divmod(num1, num2)
num3 = bi3.Item1
Return bi3.Item2
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 DivMod(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.[rem](num1, num2)
End Function
''' <summary>
''' Devuelve True si los dos números son iguales
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Equal(ByVal num1 As BigInt, ByVal num2 As BigInt) As Boolean
Return fsbim.equal(num1, num2)
End Function
''' <summary>
''' Devuelve el factorial del número indicado
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Factorial(ByVal num1 As BigInt) As BigInt
Return fsbim.factorial(num1)
End Function
''' <summary>
''' Devuelve True si el primer número es mayor que el segundo
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GT(ByVal num1 As BigInt, ByVal num2 As BigInt) As Boolean
Return fsbim.gt(num1, num2)
End Function
''' <summary>
''' Devuelve True si el primer número es mayor o igual que el segundo
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GTE(ByVal num1 As BigInt, ByVal num2 As BigInt) As Boolean
Return fsbim.gte(num1, num2)
End Function
Public Shared Function Hash(ByVal num1 As BigInt) As Integer
Return fsbim.hash(num1)
End Function
Public Shared Function HCF(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.hcf(num1, num2)
End Function
''' <summary>
''' Devuelve True si es el número 1
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function IsOne(ByVal num1 As BigInt) As Boolean
Return fsbim.isOne(num1)
End Function
''' <summary>
''' Devuelve True si es cero
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function IsZero(ByVal num1 As BigInt) As Boolean
Return fsbim.isZero(num1)
End Function
''' <summary>
''' Devuelve True si el primer número es menor que el segundo
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function LT(ByVal num1 As BigInt, ByVal num2 As BigInt) As Boolean
Return fsbim.lt(num1, num2)
End Function
''' <summary>
''' Devuelve True si el primer número es menor o igual que el segundo
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function LTE(ByVal num1 As BigInt, ByVal num2 As BigInt) As Boolean
Return fsbim.lte(num1, num2)
End Function
''' <summary>
''' Devuelve el valor mayor de los dos indicados
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Max(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.max(num1, num2)
End Function
''' <summary>
''' Devuelve el valor menor de los dos indicados
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Min(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.min(num1, num2)
End Function
''' <summary>
''' Multiplica los dos números
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Mul(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.mul(num1, num2)
End Function
''' <summary>
''' Devuelve el número en formato negativo
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Neg(ByVal num1 As BigInt) As BigInt
Return fsbim.neg(num1.Value)
End Function
''' <summary>
''' Devuelve True si el número es negativo
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Negative(ByVal num1 As BigInt) As Boolean
Return fsbim.negative(num1.Value)
End Function
''' <summary>
''' Devuelve un valor 1
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Shared ReadOnly Property One() As BigInt
Get
Return fsbim.one
End Get
End Property
''' <summary>
''' Devuelve True si el número es positivo
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Positive(ByVal num1 As BigInt) As Boolean
Return fsbim.positive(num1.Value)
End Function
''' <summary>
''' Devuelve el número elevado a la potencia indicada en el segundo parámetro
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Pow(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.pow(num1, num2)
End Function
''' <summary>
''' Devuelve el número elevado a la potencia indicada en el segundo parámetro
''' El segundo parámetro es de tipo Int32
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Pow(ByVal num1 As BigInt, ByVal num2 As Integer) As BigInt
Return fsbim.powi(num1, num2)
End Function
''' <summary>
''' Devuelve el número elevado a la potencia indicada en el segundo parámetro
''' El segundo parámetro es de tipo Int32
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function PowI(ByVal num1 As BigInt, ByVal num2 As Integer) As BigInt
Return fsbim.powi(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 [Rem](ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.[rem](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 BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.[rem](num1, num2)
End Function
''' <summary>
''' El máximo de decimales a devolver
''' </summary>
''' <remarks></remarks>
Public Const MaxDecimalesMaxValue As Integer = 1000 ' 19
''' <summary>
''' El mínimo de decimales a devolver
''' </summary>
''' <remarks></remarks>
Public Const MaxDecimalesMinValue As Integer = 0
''' <summary>
''' La misma precisión (30) que la calculadora de Windows
''' </summary>
''' <remarks></remarks>
Private Shared m_MaxDecimales As Integer = 30
''' <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 m_MaxDecimales
End Get
Set(ByVal value As Integer)
If value < MaxDecimalesMinValue Then
m_MaxDecimales = MaxDecimalesMinValue
ElseIf value > MaxDecimalesMaxValue Then
m_MaxDecimales = MaxDecimalesMaxValue
Else
m_MaxDecimales = value
End If
End Set
End Property
''' <summary>
''' Ni idea, pero parece que multiplica los dos números
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Scale(ByVal num1 As Integer, ByVal num2 As BigInt) As BigInt
Return fsbim.scale(num1, num2)
End Function
''' <summary>
''' Devuleve el signo del número:
''' 1 es positivo, -1 es negativo
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Sign(ByVal num1 As BigInt) As Integer
Return fsbim.sign(num1)
End Function
''' <summary>
''' Resta los dos números
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function [Sub](ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.sub(num1, num2)
End Function
''' <summary>
''' Convierte el número en un Int32 (Integer)
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function ToInt32(ByVal num1 As BigInt) As Integer
Return fsbim.to_int(num1)
End Function
''' <summary>
''' Convierte el número en un Int64 (Long)
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function ToInt64(ByVal num1 As BigInt) As Long
Return fsbim.to_int64(num1)
End Function
''' <summary>
''' Convierte el número en un Double
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function ToDouble(ByVal num1 As BigInt) As Double
Return fsbim.to_float(num1)
End Function
''' <summary>
''' Convierte el número en una cadena
''' </summary>
''' <param name="num1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Shared Function ToString(ByVal num1 As BigInt) As String
Return fsbim.to_string(num1)
End Function
''' <summary>
''' Devuelve el valor cero
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Shared ReadOnly Property Zero() As BigInt
Get
Return fsbim.zero
End Get
End Property
''' <summary>
''' Convertir otros tipos a BigInt
''' </summary>
''' <param name="num">
''' Puede ser un String o
''' un valor numérico que se convertirá a Int64
''' </param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Parse(ByVal num As String) As BigInt
If num.Contains("E") Then
num = num.Substring(0, num.IndexOf("E"))
ElseIf num.StartsWith("N") Then
num = "0"
End If
Return New BigInt(fsbim.of_string(num))
End Function
''' <summary>
''' Convierte un Double en BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Parse(ByVal num As Double) As BigInt
Return New BigInt(fsbim.of_int64(CLng(num)))
End Function
''' <summary>
''' Convierte un BigInt de F# en BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Parse(ByVal num As fsm.BigInt) As BigInt
Return New BigInt(num)
End Function
'
' Funciones que no están en el tipo de F#
'
''' <summary>
''' Devuelve el mayor de la lista indicada
''' </summary>
''' <param name="parametros"></param>
''' <returns></returns>
''' <remarks>
''' Para que este método funcione hay que implementar IComparable
''' </remarks>
Public Shared Function Max(ByVal ParamArray parametros() As BigInt) As BigInt
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>
''' Para que este método funcione hay que implementar IComparable
''' </remarks>
Public Shared Function Min(ByVal ParamArray parametros() As BigInt) As BigInt
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 BigInt) As BigInt
Dim t As BigInt = 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 BigInt, _
ByVal ParamArray parametros() As BigInt) As BigInt
Dim t As BigInt = 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 entero BigInt
''' </summary>
''' <param name="parametros"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Media(ByVal ParamArray parametros() As BigInt) As BigInt
Dim t As BigInt = 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 BigInt, ByVal cant As BigInt) As BigInt
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 BigInt, ByVal num2 As BigInt) As BigInt
Return num1 * num2 / 100
End Function
''' <summary>
''' La versión actual de la DLL (revisión)
''' </summary>
''' <param name="conNombre">
''' Opcional (False) si se debe devolver el nombre del ensamblado
''' </param>
''' <returns>
''' La versión de la DLL (versión de FileVersion)
''' </returns>
''' <remarks></remarks>
Public Shared Function Version(ByVal conNombre As Boolean) As String
Dim ensamblado As Assembly = Assembly.GetExecutingAssembly
Dim fvi As FileVersionInfo = FileVersionInfo.GetVersionInfo(ensamblado.Location)
If conNombre Then
Return ensamblado.GetName.Name & " v" & fvi.FileVersion
Else
Return " v" & fvi.FileVersion
End If
End Function
''' <summary>
''' La versión actual de la DLL (revisión)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Version() As String
Return Version(False)
End Function
''' <summary>
''' El factor mayor de un número (factorMax)
''' El númeo mayor que divide exactamente al número
''' Si no lo hay ninguno, devuelve cero (normalmente será primo)
''' </summary>
''' <param name="a"></param>
''' <returns></returns>
''' <remarks>
''' Esta operación es lenta si el número es muy grande
''' </remarks>
Public Shared Function FactorMayor(ByVal a As BigInt) As BigInt
Dim i As BigInt = System.Math.Sqrt(a) + 1
Dim bi2 As BigInt = 2
While BigInt.GT(i, bi2)
If BigInt.Equal(BigInt.Mod(a, i), BigInt.Zero) Then
Return i
End If
'If a Mod i = BigInt.Zero Then
' Return i
'End If
i = BigInt.Sub(i, BigInt.One)
'i = i - BigInt.One
End While
Return BigInt.Zero
End Function
''' <summary>
''' Devuelve el factor menor de un número
''' El número menor que lo divide exactamente
''' Si no hay, devuelve cero (normalmente será número primo)
''' </summary>
''' <param name="a"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function FactorMenor(ByVal a As BigInt) As BigInt
' Si es divisible por dos
Dim bi2 As BigInt = 2
If BigInt.Equal(BigInt.Mod(a, bi2), BigInt.Zero) Then
Return bi2
End If
'If a Mod 2 = 0 Then
' Return 2
'End If
' Comprobar desde el 3 hasta la raíz cuadrada
' seguir comprobando de dos en dos
Dim m As BigInt = System.Math.Sqrt(a) + 1
Dim i As BigInt = 3
While i < m
If BigInt.Equal(BigInt.Mod(a, i), BigInt.Zero) Then
Return i
End If
i = BigInt.Add(i, bi2)
'If a Mod i = 0 Then
' Return i
'End If
'i = i + 2
End While
Return BigInt.Zero
End Function
''' <summary>
''' Comprueba si el número es primo
''' Devuelve True si es primo, o False si no lo es
''' El número 1 se considera como primo
''' </summary>
''' <param name="a"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function EsPrimo(ByVal a As BigInt) As Boolean
If a = 1 OrElse a = 2 OrElse a = 3 Then
Return True
End If
' Si es par, no es primo
Dim bi2 As BigInt = 2
If BigInt.Equal(BigInt.Mod(a, bi2), BigInt.Zero) Then
Return False
End If
'If a Mod 2 = 0 Then
' Return 0
'End If
' Empezar a comprobar desde el 3
' hasta la raíz cuadrada del número
Dim m As BigInt = System.Math.Sqrt(a) + 1
Dim i As BigInt = 3
While i < m
' Si es divisible por i, es que no es primo
If BigInt.Equal(BigInt.Mod(a, i), BigInt.Zero) Then
Return False
End If
i = BigInt.Add(i, bi2)
'If a Mod i = 0 Then
' Return 0
'End If
'i = i + 2
End While
Return True
End Function
''' <summary>
''' La raíz cuadrada de un número
''' El valor máximo es el de un Double
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Sqrt(ByVal num As BigInt) As BigInt
Return System.Math.Sqrt(num)
End Function
''' <summary>
''' Suma dos números
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Sum(ByVal num1 As BigInt, ByVal num2 As BigInt) As BigInt
Return fsbim.add(num1, num2)
End Function
''' <summary>
''' Divide dos números
''' Devuelve la parte fraccionaria (máximo MaxDecimales dígitos)
''' En el tercer parámetro se devuelve la parte entera
''' </summary>
''' <param name="num1"></param>
''' <param name="num2"></param>
''' <param name="num3"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function DivFrac(ByVal num1 As BigInt, ByVal num2 As BigInt, _
ByRef num3 As BigInt) As String
Dim bi3 As fsc.Tuple(Of fsm.BigInt, fsm.BigInt) = _
fsm.BigIntModule.divmod(num1, num2)
num3 = bi3.Item1 ' Parte entera
Dim bi4 As BigInt = bi3.Item2
Dim sb As New System.Text.StringBuilder
Dim n3 As BigInt = BigInt.Zero
For i As Integer = 1 To MaxDecimales
num1 = bi4 * 10
bi4 = BigInt.DivMod(num1, num2, n3)
sb.Append(BigInt.Abs(n3).ToString)
Next
Return sb.ToString().TrimEnd("0".ToCharArray)
End Function
''' <summary>
''' Devuelve PI como número entero con 260 decimales
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>
''' No creo que tenga utilidad, pero...
''' </remarks>
Public Shared ReadOnly Property PI() As BigInt
Get
' Valor de la página
' http://centros5.pntic.mec.es/ies.de.bullas/dp/matema/conocer/pi_1500.htm
Dim s As New StringBuilder(260)
s.Append("3")
s.Append("14159265358979323846264338327950288419716939937510")
s.Append("58209749445923078164062862089986280348253421170679")
s.Append("82148086513282306647093844609550582231725359408128")
s.Append("48111745028410270193852110555964462294895493038196")
s.Append("44288109756659334461284756482337867831652712019091")
' Si añades más decimales, recuerda redondear si es necesario
' aquí tienes hasta el dígito 440 (que puedes usar sin redondear)
' 4564856692 3460348610 4543266482 1339360726 0249141273
' 7245870066 0631558817 4881520920 9628292540 9171536436
' 7892590360 0113305305 4882046652 1384146951 9415116094
' 7363717872 1468440901 2249534301 4654958537
Return Parse(s.ToString)
End Get
End Property
''' <summary>
''' Devuelve el
''' Máximo Común Divisor / Greatest Common Divisor
''' </summary>
''' <param name="a"></param>
''' <param name="b"></param>
''' <returns></returns>
''' <remarks>
''' Usa el teorema de Euclides mejorado
''' </remarks>
Public Shared Function MCD(ByVal a As BigInt, ByVal b As BigInt) As BigInt
While a > 0
Dim c As BigInt = a
a = b Mod a
b = c
End While
Return b
End Function
''' <summary>
''' Devuelve el
''' Máximo Común Divisor / Greatest Common Divisor
''' </summary>
''' <param name="a"></param>
''' <param name="b"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GCD(ByVal a As BigInt, ByVal b As BigInt) As BigInt
Return MCD(a, b)
End Function
''' <summary>
''' Mínimo Común Múltiplo / Least Common Multiple
''' Es el producto de dos números dividido por el mcd
''' </summary>
''' <param name="a"></param>
''' <param name="b"></param>
''' <returns></returns>
''' <remarks>
''' </remarks>
Public Shared Function MCM(ByVal a As BigInt, ByVal b As BigInt) As BigInt
Dim c As BigInt = MCD(a, b)
Dim t As BigInt = a * b
Return t \ c
End Function
''' <summary>
''' Mínimo Común Múltiplo / Least Common Multiple
''' Es el producto de dos números dividido por el mcd
''' </summary>
''' <param name="a"></param>
''' <param name="b"></param>
''' <returns></returns>
''' <remarks>
''' </remarks>
Public Shared Function LCM(ByVal a As BigInt, ByVal b As BigInt) As BigInt
Return MCM(a, b)
End Function
'
' Constructores personalizados
'
''' <summary>
''' Crear un nuevo objeto a partir de una cadena o
''' un valor numérico que se convertirá a Int64
''' </summary>
''' <param name="num"></param>
''' <remarks></remarks>
Public Sub New(ByVal num As String)
Value = Parse(num)
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)
Value = Parse(num)
End Sub
''' <summary>
''' Crea un objeto a partir de un BigInt de F#
''' </summary>
''' <param name="num"></param>
''' <remarks></remarks>
Public Sub New(ByVal num As fsm.BigInt)
Value = num
End Sub
'
' Métodos de instancia
'
''' <summary>
''' Devuelve el número como una cadena
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Overrides Function ToString() As String
Return fsbim.to_string(Value)
End Function
''' <summary>
''' Devuelve True si este número es cero
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function IsZero() As Boolean
Return fsbim.isZero(Me.Value)
End Function
''' <summary>
''' Convierte el número en un Int32 (Integer)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function ToInt32() As Integer
Return fsbim.to_int(Me.Value)
End Function
''' <summary>
''' Convierte el número en un Int64 (Long)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function ToInt64() As Long
Return fsbim.to_int64(Me.Value)
End Function
''' <summary>
''' Convierte el número en un Double
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function ToDouble() As Double
Return fsbim.to_float(Me.Value)
End Function
'
' Conversiones personalizadas
'
''' <summary>
''' Convierte un BigInt de F# en un BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As fsm.BigInt) As BigInt
Return Parse(num)
End Operator
''' <summary>
''' Convierte un BigInt en un BigInt de F#
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As BigInt) As fsm.BigInt
Return num.Value
End Operator
''' <summary>
''' Convierte un valor numérico en un BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As Double) As BigInt
Return Parse(num)
End Operator
''' <summary>
''' Convierte un ULong en un BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As ULong) As BigInt
Return Parse(num.ToString)
End Operator
''' <summary>
''' Convierte una cadena en un BigInt
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As String) As BigInt
Return Parse(num)
End Operator
' Conversiones de BigInt a otros tipos
''' <summary>
''' Convierte un BigInt en una cadena
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As BigInt) As String
Return fsbim.to_string(num.Value)
End Operator
' Estos pueden tener pérdida de información
' Dejo estas sobrecargas para que se puedan convertir más o menos bien
''' <summary>
''' Convierte un BigInt en un Double
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal num As BigInt) As Double
Return fsbim.to_float(num.Value)
End Operator
''' <summary>
''' Convierte un BigInt en un Int64 (Long)
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Narrowing Operator CType(ByVal num As BigInt) As Long
Return fsbim.to_int64(num.Value)
End Operator
''' <summary>
''' Convierte un BigInt en un Int32 (Integer)
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Narrowing Operator CType(ByVal num As BigInt) As Integer
Return fsbim.to_int(num.Value)
End Operator
''' <summary>
''' Convierte un BigInt en un UInt32 (UInteger)
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Narrowing Operator CType(ByVal num As BigInt) As UInteger
Return CUInt(fsbim.to_int64(num.Value))
End Operator
' El valor máximo de ULong es:
' 18.446.744.073.709.551.615 / 0xFFFFFFFFFFFFFFFF
''' <summary>
''' Convierte un BigInt en un UInt64 (ULong)
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Narrowing Operator CType(ByVal num As BigInt) As ULong
Return CULng(fsbim.to_int64(num.Value))
''Return CULng(fsbim.to_string(num.Value))
End Operator
' El valor máximo de un decimal es:
' 79228162514264337593543950335 (29 cifras)
' 79.228.162.514.264.337.593.543.950.335
''' <summary>
''' Convierte un BigInt en un Decimal
''' </summary>
''' <param name="num"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Narrowing Operator CType(ByVal num As BigInt) As Decimal
Try
Return CDec(fsbim.to_string(num.Value))
Catch ex As Exception
'Return Decimal.MaxValue
Return CULng(fsbim.to_int64(num.Value))
End Try
End Operator
'
' Sobrecarga de operadores
'
'
' Sobrecarga de operadores aritméticos
'
''' <summary>
''' Operador unario devuelve el mismo número
''' </summary>
''' <param name="bn1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator +(ByVal bn1 As BigInt) As BigInt
Return bn1
End Operator
''' <summary>
''' Operador unario, niega el número
''' Si es positivo lo devuelve negativo y viceversa
''' </summary>
''' <param name="bn1"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator -(ByVal bn1 As BigInt) As BigInt
Return BigInt.Neg(bn1)
End Operator
''' <summary>
''' Suma dos valores
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator +(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Add(bn1, bn2)
End Operator
''' <summary>
''' Resta dos valores
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator -(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Sub(bn1, bn2)
End Operator
''' <summary>
''' Multiplica dos valores
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator *(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Mul(bn1, bn2)
End Operator
''' <summary>
''' Divide dos valores
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator /(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Div(bn1, bn2)
End Operator
''' <summary>
''' Divide dos valores
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator \(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Div(bn1, bn2)
End Operator
''' <summary>
''' Devuelve el resto de la división del primero por el segundo
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Mod(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Mod(bn1, bn2)
End Operator
''' <summary>
''' Eleva el primero número a la potencia indicada en el segundo
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator ^(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As BigInt
Return BigInt.Pow(bn1, bn2)
End Operator
''' <summary>
''' Sobrecarga del operador de concatenación
''' entre dos BigInt
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks>
''' v.0.1 19/Oct/07
''' </remarks>
Public Shared Operator &(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As String
Return bn1.ToString & bn2.ToString
End Operator
' Estas dos sobrecargas es para evitar convertir una cadena a BigInt
' cuando los parámetros no son BigInt
''' <summary>
''' Sobrecarga del operador de concatenación entre un BigInt y una cadena
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator &(ByVal bn1 As BigInt, ByVal bn2 As String) As String
Return bn1.ToString & bn2
End Operator
''' <summary>
''' Sobrecarga del operador de concatenación entre una cadena y un BigInt
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator &(ByVal bn1 As String, ByVal bn2 As BigInt) As String
Return bn1 & bn2.ToString
End Operator
'
' Sobrecarga de operadores de comparación
'
''' <summary>
''' Devuelve True si son iguales
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator =(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return BigInt.Equal(bn1, bn2)
End Operator
''' <summary>
''' Devuelve True si son distintos
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator <>(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return Not BigInt.Equal(bn1, bn2)
End Operator
''' <summary>
''' Devuelve True si el primero es menor
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator <(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return BigInt.LT(bn1, bn2)
End Operator
''' <summary>
''' Devuelve True si el primero es mayor
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator >(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return BigInt.GT(bn1, bn2)
End Operator
''' <summary>
''' Devuelve True si el primero es menor o igual
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator <=(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return BigInt.LTE(bn1, bn2)
End Operator
''' <summary>
''' Devuelve True si el primero es mayor o igual
''' </summary>
''' <param name="bn1"></param>
''' <param name="bn2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator >=(ByVal bn1 As BigInt, ByVal bn2 As BigInt) As Boolean
Return BigInt.GTE(bn1, bn2)
End Operator
'
' Sobrecarga de operadores booleanos
'
''' <summary>
''' Devuelve True si no es cero
''' </summary>
''' <param name="bn"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator IsTrue(ByVal bn As BigInt) As Boolean
Return Not BigInt.IsZero(bn)
End Operator
''' <summary>
''' Devuelve True si es cero
''' </summary>
''' <param name="bn"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator IsFalse(ByVal bn As BigInt) As Boolean
Return BigInt.IsZero(bn)
End Operator
End Structure