Índice de la sección dedicada a .NET (en el Guille) Cómo... en .NET

Operar con números grandes
(rev 0.1 y 0.2)

Cómo realizar operaciones con números enteros demasiados grandes que ni el propio .NET puede realizar

Código para Visual Basic.NET (VB.NET)

Código para Visual Basic 6.0 (o anterior a .NET)

Código para C Sharp (C#)


Actualizado el 11/Ago/2004
Autor: Guillermo 'guille' Som

 

Contenido:

 

Novedades en la revisión 0.1:

Bueno, pues esto ya parece otra cosa... o casi...
Estas son las nuevas cosas de esta revisión:
-Ahora está en una clase (o estructura) llamada Real con los métodos estáticos (compartidos)
-Se pueden realizar divisiones.
-Se admiten operaciones con decimales (fracciones)
-Se puede indicar el número máximo de decimales (incluso cero) por medio de NumDecimales (valor predeterminado = 4)
-En las divisiones se puede indicar que se muestre el resto (MostrarResto = True)

 

Novedades en la revisión 0.2 (sólo en C#):

La revisión 0.2 es la versión de C# con sobrecarga de operadores, conversiones de tipos y otras cosillas, como la de comprobar si un número es menor que otro... que aunque parezca fácil, no lo es tanto, ya que al ser cadenas de caracteres las comparaciones no funcionan igual que en los números.

En el código de C# he creado una estructura, que además de tener los métodos (funciones) de la versión "normal" he añadido ciertas sobrecargas como la de la suma (+), la resta (-), la multiplicación (*) y la división (/), no he sobrecargado la exponenciación porque C# no tiene...
También he creado las siguientes conversiones:
-De Real a String
-De String a Real
-De Real a int (explícita, hay que hacer cast)
-De long a Real (y por extensión cualquier tipo inferior, int, etc.)
-De decimal a Real
-De double a Real (y también float)
-Los operadores booleanos <, >, == y !=

Para usarlo se haría algo así:
Real r1;
r1 = "123456";
r1.Valor = "123456";
Real r2 = new Real("952145.50");
Console.WriteLine( r1 * r2);

Pero esta librería sólo se puede usar en C# (al menos para poder usar las sobrecargas)
Si se quiere usar con Visual Basic habrá que usar los métodos equivalentes a los operadores sobrecargados:
*  op_Multiply
/  op_Division
+  op_Addition
-  op_Substraction
== op_Equality
!= op_Inequality
<  op_LessThan
>  op_GreaterThan

Además de las conversiones (implícitas o explícitas):
op_Implicit
op_Explicit (sólo la que convierte de Real a Integer)
 

La verdad es que esto de las sobrecargas de C# me tenían engañado... siempre había pensado que también se podrían usar en Visual Basic de la misma forma que en C#. En fin... habrá que esperar a la versión 2005 para que se puedan usar las sobrecargas de forma indistinta, es decir, sin que importe con que lenguaje se ha escrito y con cual se utiliza.

El código mostrado de Visual Basic es el "casi" equivalente a C#, pero sin las sobrecargas.
El código mostrado de C# es el que incluye las sobrecargas de operadores y conversiones.

Nos vemos.
Guillermo
P.S.
Si alguien se anima a colaborar en este proyecto... podríamos hacer algo realmente útil.


Código para Visual Basic.NET (VB.NET)El código para VB .NET

 

'------------------------------------------------------------------------------
' Multiplicar números usando cadenas de caracteres                    (10/Ago/04)
'
' Realizar operaciones con números de cualquier longitud
' Admite decimales                                                  (11/Ago/04)
'
' Operaciones soportadas:
'    Multiplicación, División, Potencia, Suma y Resta
'
' ©Guillermo 'guille' Som, 2004
'------------------------------------------------------------------------------
Option Explicit On 
Option Strict On

Imports System

Namespace elGuille.Math
    Public Class Real
        Friend Shared ad() As String
        Public Shared NumDecimales As Integer = 4
        Public Shared MostrarResto As Boolean = False
        '
        '
        Private Shared Function miDiv2(ByVal num1 As String, ByVal num2 As String, ByVal decAct As Integer) As String
            Dim res As String = num1
            Dim n As Integer = 0
            If num2.Length < num1.Length Then
                num2 = (New String("0"c, num1.Length) & num2).Substring(num2.Length, num1.Length)
            End If
            Do
                res = miResta2(res, num2)
                n += 1
                If res = "0" OrElse res < num2 Then Exit Do
            Loop
            res = quitarCeros(res)
            If res <> "0" Then
                If decAct < NumDecimales Then
                    decAct += 1
                    res = miDiv2(res & "0", num2, decAct)
                    ' quitar los puntos que haya
                    res = res.Replace(".", "")
                    Return n.ToString & "." & res
                Else
                    ' si queda un resto mostrarlo con :
                    ' (o bien no mostrarlo)
                    If MostrarResto Then
                        Return n.ToString & ":" & res
                    Else
                        Return n.ToString '& ":" & res
                    End If
                End If
            Else
                Return n.ToString
            End If
        End Function
        Public Shared Function Div2(ByVal num1 As String, ByVal num2 As String) As String
            ' Para dividir dos números:
            ' Se leva restando al dividendo el divisor hasta que
            ' el resto sea cero o menor que el divisor
            Dim decAct As Integer = 0
            '
            Dim nDec1 As Integer
            Dim nDec2 As Integer
            Dim dec1 As Integer = num1.IndexOf(".")
            Dim dec2 As Integer = num2.IndexOf(".")
            If dec1 > -1 Then
                num1 = quitarCerosFinales(num1)
                nDec1 = num1.Substring(dec1 + 1).Length
                num1 = num1.Replace(".", "")
            End If
            If dec2 > -1 Then
                num2 = quitarCerosFinales(num2)
                nDec2 = num2.Substring(dec2 + 1).Length
                num2 = num2.Replace(".", "")
            End If
            If nDec1 > 0 Then
                num2 = num2 & New String("0"c, nDec1)
            End If
            If nDec2 > 0 Then
                num1 = num1 & New String("0"c, nDec2)
            End If
            '
            Return miDiv2(num1, num2, decAct)
        End Function
        '
        Public Shared Function PotN(ByVal num1 As String, ByVal elevado As String) As String
            Dim i As Integer
            '
            ' si el exponente tiene decimales, quitárselo
            i = elevado.IndexOf(".")
            If i > -1 Then
                elevado = elevado.Substring(0, i)
            End If
            '
            If elevado = "0" Then
                Return "1"
            ElseIf elevado = "1" Then
                Return num1
            End If
            If num1 = "1" Then
                Return "1"
            ElseIf num1 = "0" Then
                Return "0"
            End If
            '
            i = CInt(elevado) - 1
            Dim p(i) As String
            For k As Integer = 0 To i
                p(k) = num1
            Next
            Return Mult2(p)
        End Function
        '
        Public Shared Function Mult2(ByVal ParamArray nums() As String) As String
            Dim total As String = nums(0)
            For i As Integer = 1 To nums.Length - 1
                Dim n1 As String = nums(i)
                total = Mult2(total, n1)
            Next
            '
            Return total
        End Function
        Public Shared Function Mult2(ByVal num1 As String, ByVal num2 As String) As String
            '
            ' Comprobar si alguno de los números tiene decimales        (11/Ago/04)
            Dim nDec As Integer
            '
            Dim dec1 As Integer = num1.IndexOf(".")
            Dim dec2 As Integer = num2.IndexOf(".")
            If dec1 > -1 Then
                nDec = num1.Substring(dec1 + 1).Length
                num1 = num1.Replace(".", "")
            End If
            If dec2 > -1 Then
                nDec += num2.Substring(dec2 + 1).Length
                num2 = num2.Replace(".", "")
            End If
            '
            ' Poner el más largo como primer número
            If num2.Length > num1.Length Then
                Swap(num1, num2)
            End If
            '
            ' El número de operaciones necesarias
            ' será la cantidad de cifras del más pequeño
            ReDim ad(num2.Length - 1)
            Dim n As Integer = -1
            Dim resto As String = "0"
            Dim res As String = ""
            '
            ' Multiplicar formando filas con los resultados (al estilo manual)
            For i As Integer = num2.Length - 1 To 0 Step -1
                n += 1
                ad(n) = ""
                ' Añadir espacios a la derecha según la cifra (fila) que se procese
                For k As Integer = 1 To n
                    ad(n) &= " "
                Next
                Dim c1 As String = num2.Substring(i, 1)
                ' Para simplificar las cosas
                ' se comprueba si se multiplicará por ceo o por uno
                ' de forma que no sea necesario hacer estas operaciones
                If c1 = "0" Then
                    ad(n) = New String("0"c, num1.Length) & ad(n)
                ElseIf c1 = "1" Then
                    ad(n) = num1 & ad(n)
                Else
                    For j As Integer = num1.Length - 1 To 0 Step -1
                        Dim c2 As String = num1.Substring(j, 1)
                        res = (CInt("0" & c1) * CInt("0" & c2) + CInt(resto)).ToString
                        'ad(n) = vb.Right(res, 1) & ad(n)
                        ad(n) = res.Substring(res.Length - 1, 1) & ad(n)
                        If res.Length - 1 < 1 Then
                            resto = "0"
                        Else
                            resto = res.Substring(0, res.Length - 1)
                        End If
                    Next
                    If resto <> "0" Then
                        ad(n) = resto & ad(n)
                        resto = "0"
                    End If
                End If
            Next
            '
            res = sumarFilas()
            If nDec > 0 Then
                If NumDecimales = 0 Then
                    res = res.Substring(0, res.Length - nDec)
                Else
                    resto = res.Substring(res.Length - nDec)
                    If resto.Length > NumDecimales Then
                        resto = resto.Substring(0, NumDecimales)
                    End If
                    res = res.Substring(0, res.Length - nDec) & "." & quitarCerosFinales(resto)
                End If
            End If
            Return res
        End Function
        '
        Public Shared Function Suma2(ByVal ParamArray nums() As String) As String
            '
            ReDim ad(nums.Length - 1)
            For i As Integer = 0 To nums.Length - 1
                ad(i) = nums(i)
            Next
            '
            Return sumarFilas()
        End Function
        Public Shared Function Suma2(ByVal num1 As String, ByVal num2 As String) As String
            ReDim ad(1)
            '
            Dim nDec As Integer
            Dim nDec1 As Integer
            Dim nDec2 As Integer
            Dim dec1 As Integer = num1.IndexOf(".")
            Dim dec2 As Integer = num2.IndexOf(".")
            If dec1 > -1 Then
                num1 = quitarCerosFinales(num1)
                nDec1 = num1.Substring(dec1 + 1).Length
                num1 = num1.Replace(".", "")
            End If
            If dec2 > -1 Then
                num2 = quitarCerosFinales(num2)
                nDec2 = num2.Substring(dec2 + 1).Length
                num2 = num2.Replace(".", "")
            End If
            If nDec1 > 0 Then
                num2 = num2 & New String("0"c, nDec1)
            End If
            If nDec2 > 0 Then
                num1 = num1 & New String("0"c, nDec2)
            End If
            nDec = nDec1 + nDec2
            '
            ad(0) = num1
            ad(1) = num2
            '
            'Return sumarFilas()
            '
            Dim res As String = sumarFilas()
            Dim resto As String = ""
            If nDec > 0 Then
                If NumDecimales = 0 Then
                    res = res.Substring(0, res.Length - nDec)
                Else
                    resto = res.Substring(res.Length - nDec)
                    If resto.Length > NumDecimales Then
                        resto = resto.Substring(0, NumDecimales)
                    End If
                    res = res.Substring(0, res.Length - nDec) & "." & quitarCerosFinales(resto)
                End If
            End If
            Return res
        End Function
        '
        Public Shared Function Resta2(ByVal ParamArray nums() As String) As String
            Dim total As String = nums(0)
            For i As Integer = 1 To nums.Length - 1
                Dim n1 As String = nums(i)
                total = miResta2(total, n1)
            Next
            '
            Return total
        End Function
        Private Shared Function miResta2(ByVal num1 As String, ByVal num2 As String) As String
            ' usar esta función para cálculos internos en los que no se deben quitar
            ' los ceros del principio del número
            ReDim ad(1)
            '
            Dim nDec As Integer
            Dim nDec1 As Integer
            Dim nDec2 As Integer
            Dim dec1 As Integer = num1.IndexOf(".")
            Dim dec2 As Integer = num2.IndexOf(".")
            If dec1 > -1 Then
                num1 = quitarCerosFinales(num1)
                nDec1 = num1.Substring(dec1 + 1).Length
                num1 = num1.Replace(".", "")
            End If
            If dec2 > -1 Then
                num2 = quitarCerosFinales(num2)
                nDec2 = num2.Substring(dec2 + 1).Length
                num2 = num2.Replace(".", "")
            End If
            If nDec1 > 0 Then
                num2 = num2 & New String("0"c, nDec1)
            End If
            If nDec2 > 0 Then
                num1 = num1 & New String("0"c, nDec2)
            End If
            nDec = nDec1 + nDec2
            '
            ad(0) = num1
            ad(1) = num2
            '
            'Return restar2Filas()
            '
            Dim res As String = restar2Filas()
            Dim resto As String = ""
            If nDec > 0 Then
                If NumDecimales = 0 Then
                    res = res.Substring(0, res.Length - nDec)
                Else
                    resto = res.Substring(res.Length - nDec)
                    If resto.Length > NumDecimales Then
                        resto = resto.Substring(0, NumDecimales)
                    End If
                    res = res.Substring(0, res.Length - nDec) & "." & quitarCerosFinales(resto)
                End If
            End If
            Return res
        End Function
        Public Shared Function Resta2(ByVal num1 As String, ByVal num2 As String) As String
            Return quitarCeros(miResta2(num1, num2))
        End Function
        '
        Private Shared Function sumarFilas() As String
            Dim m As Integer = 0
            Dim n As Integer = ad.Length - 1
            '
            ' m será el número de mayor longitud
            For k As Integer = 0 To n
                If ad(k).Length > m Then m = ad(k).Length
            Next
            '
            ' sumar las filas obtenidas
            Dim resto As String = "0"
            Dim total As String = ""
            Dim res As String = ""
            '
            For k As Integer = 0 To n
                'ad(k) = vb.Right(New String(" "c, m) & ad(k), m)
                ad(k) = (New String(" "c, m) & ad(k)).Substring(ad(k).Length, m)
            Next
            For k As Integer = m - 1 To 0 Step -1
                res = resto
                For i As Integer = 0 To n
                    res = (CInt(res) + CInt("0" & ad(i).Substring(k, 1))).ToString
                Next
                'total = vb.Right(res, 1) & total
                total = res.Substring(res.Length - 1, 1) & total
                If res.Length - 1 < 1 Then
                    resto = "0"
                Else
                    resto = res.Substring(0, res.Length - 1)
                End If
            Next
            If resto <> "0" Then
                total = resto & total
            End If
            '
            Return total
        End Function
        '
        Private Shared Function restar2Filas() As String
            Dim m As Integer = 0
            Dim n As Integer = ad.Length - 1
            '
            For k As Integer = 0 To n
                If ad(k).Length > m Then m = ad(k).Length
            Next
            '
            ' restar las filas obtenidas
            Dim resto As String = "0"
            Dim total As String = ""
            Dim res As String = ""
            '
            For k As Integer = 0 To n
                'ad(k) = vb.Right(New String(" "c, m) & ad(k), m)
                ad(k) = (New String("0"c, m) & ad(k)).Substring(ad(k).Length, m)
            Next
            For k As Integer = m - 1 To 0 Step -1
                res = (CInt("0" & ad(0).Substring(k, 1)) - (CInt("0" & ad(1).Substring(k, 1)) + CInt(resto))).ToString
                If CInt(res) < 0 Then
                    res = (CInt(res) + 10).ToString
                    res = "1" & res
                End If
                'total = vb.Right(res, 1) & total
                total = res.Substring(res.Length - 1, 1) & total
                If res.Length - 1 < 1 Then
                    resto = "0"
                Else
                    resto = res.Substring(0, res.Length - 1)
                End If
            Next
            If resto <> "0" Then
                total = resto & total
            End If
            '
            Return total
        End Function
        '
        Public Shared Sub Swap(ByRef n1 As String, ByRef n2 As String)
            Dim t As String = n1
            n1 = n2
            n2 = t
        End Sub
        '
        Private Shared Function quitarCeros(ByVal num As String) As String
            '
            ' Si tiene varios ceros, dejar sólo uno
            While num.StartsWith("0")
                If num = "0" Then Exit While
                num = num.Substring(1)
            End While
            Return num
        End Function
        Private Shared Function quitarCerosFinales(ByVal num As String) As String
            '
            ' Si tiene varios ceros, dejar sólo uno
            While num.EndsWith("0")
                If num = "0" Then Exit While
                num = num.Substring(0, num.Length - 1)
            End While
            Return num
        End Function
    End Class
End Namespace

 


Código para C Sharp (C#)El código para C#

El código de prueba

 

using System;
using elGuille.Math;
 
class PruebaRealCS{
    static void Main(string[] args) {
        //
        Real r1;
        Real r2;
        r1.Valor = "250";
        r2.Valor = "2";
        Console.WriteLine("{0} + {1} = {2}",r1, r2, r1 + r2); 
        string s1 = "22";
        Console.WriteLine("{0} + {1} = {2}", s1, r2, s1 + r2); 
        //
        string s2 = r1;
        string s3 = "125";
        Real r3;
        r3 = (Real)s3;
        Console.WriteLine("s2 = {0}", s2);
        Console.WriteLine("r3 = {0}", r3);
        //
        int i1 = 139;
        Real r4 = i1;
        Console.WriteLine("r4 = {0}", r4);
        Real r5 = r4 + i1;
        Console.WriteLine("r4 + i1 = {0}", r5);
        //
        decimal m1 = 125.50M;
        Real r6 = m1;
        Console.WriteLine("r6 = {0}", r6);
        //
        Real r7 = new Real("125.46");
        Console.WriteLine("r7 = {0}", r7);
        //
        long l1 = 125987;
        Real r8 = l1;
        Console.WriteLine("r8 = {0}", r8);
        //
        float f1 = 1234.440F;
        Real r9 = (double)f1;
        Console.WriteLine("r9 = {0}", r9);
        //
        Console.Write("EsMenor(9988.5578, 1239.95) = ");
        Console.WriteLine(Real.EsMenor("9988.5578","1239.95"));
        Console.Write("EsMenor(123456, 12398745) ");
        Console.WriteLine(Real.EsMenor("123456","12398745"));
        Console.Write("EsMenor(123456789, 12398745) ");
        Console.WriteLine(Real.EsMenor("123456789","12398745"));
        //
        Console.WriteLine("{0} > {1} = {2}",r7, r8, r7 > r8);
        Console.WriteLine("{0} < {1} = {2}",r7, r8, r7 < r8);
        //
        //
        Console.ReadLine();
        return;
        //
    }  
    //
    private static void pruebaPot() {
        Console.WriteLine("Prueba de Potencia");
        Console.WriteLine();
        //
        string num1;
        string num2;
        Real.NumDecimales = 4;
        Real.MostrarResto = true;
        Console.WriteLine("Decimales: {0}", Real.NumDecimales);
        Console.WriteLine("Mostrar resto: {0}", Real.MostrarResto);
        Console.WriteLine();
        num1 = "5";
        num2 = "2";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "2";
        num2 = "3";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "25";
        num2 = "2";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "10";
        num2 = "3";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "2";
        num2 = "2.5";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "2.25";
        num2 = "2";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "2";
        num2 = "1";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        num1 = "2";
        num2 = "0";
        Console.WriteLine("{0} ^ {1} = {2}", num1, num2, Real.PotN(num1, num2));
        Console.WriteLine();
        //
        Console.ReadLine();
    }  
    //
    private static void pruebaResta() {
        Console.WriteLine("Prueba de Restar");
        Console.WriteLine();
        //
        string num1;
        string num2;
        Real.NumDecimales = 4;
        Real.MostrarResto = true;
        Console.WriteLine("Decimales: {0}", Real.NumDecimales);
        Console.WriteLine("Mostrar resto: {0}", Real.MostrarResto);
        Console.WriteLine();
        Real r1 = new Real("12");
        Real r2; r2.Valor = "3";
        Console.WriteLine("{0} - {1} = {2}", r1, r2, r1 - r2);
        Console.WriteLine();
        r1.Valor = "25";
        r2.Valor = "4.5";
        Console.WriteLine("{0} - {1} = {2}", r1, r2, r1 - r2);
        Console.WriteLine();
        r1 = "10";
        r2 = "2.25";
        Console.WriteLine("{0} - {1} = {2}", r1, r2, r1 - r2);
        Console.WriteLine();
        r1 = "2.50";
        r2 = "2.25";
        Console.WriteLine("{0} - {1} = {2}", r1, r2, r1 - r2);
        Console.WriteLine();
        num1 = "22.50";
        num2 = "92.25";
        Console.WriteLine("{0} - {1} = {2}", num1, num2, Real.Resta2(num1, num2));
        Console.WriteLine();
        //
        Console.ReadLine();
    }  
    //
    private static void pruebaSuma() {
        Console.WriteLine("Prueba de Sumar");
        Console.WriteLine();
        //
        string num1;
        string num2;
        Real.NumDecimales = 4;
        Real.MostrarResto = true;
        Console.WriteLine("Decimales: {0}", Real.NumDecimales);
        Console.WriteLine("Mostrar resto: {0}", Real.MostrarResto);
        Console.WriteLine();
        num1 = "12";
        num2 = "3";
        Console.WriteLine("{0} + {1} = {2}", num1, num2, Real.Suma2(num1, num2));
        Console.WriteLine();
        num1 = "25";
        num2 = "4.5";
        Console.WriteLine("{0} + {1} = {2}", num1, num2, Real.Suma2(num1, num2));
        Console.WriteLine();
        num1 = "10";
        num2 = "2.25";
        Console.WriteLine("{0} + {1} = {2}", num1, num2, Real.Suma2(num1, num2));
        Console.WriteLine();
        num1 = "2.50";
        num2 = "2.25";
        Console.WriteLine("{0} + {1} = {2}", num1, num2, Real.Suma2(num1, num2));
        Console.WriteLine();
        //
        Console.ReadLine();
    }  
    //
    private static void pruebaMult() {
        Console.WriteLine("Prueba de Multiplicar");
        Console.WriteLine();
        //
        string num1;
        string num2;
        Real.NumDecimales = 4;
        Real.MostrarResto = true;
        Console.WriteLine("Decimales: {0}", Real.NumDecimales);
        Console.WriteLine("Mostrar resto: {0}", Real.MostrarResto);
        Console.WriteLine();
        num1 = "12";
        num2 = "3";
        Console.WriteLine("{0} * {1} = {2}", num1, num2, Real.Mult2(num1, num2));
        Console.WriteLine();
        num1 = "25";
        num2 = "4.5";
        Console.WriteLine("{0} * {1} = {2}", num1, num2, Real.Mult2(num1, num2));
        Console.WriteLine();
        num1 = "10";
        num2 = "2.25";
        Console.WriteLine("{0} * {1} = {2}", num1, num2, Real.Mult2(num1, num2));
        Console.WriteLine();
        num1 = "10";
        num2 = "100";
        Console.WriteLine("{0} * {1} = {2}", num1, num2, Real.Mult2(num1, num2));
        Console.WriteLine();
        num1 = "10.5";
        num2 = "20.25";
        Console.WriteLine("{0} * {1} = {2}", num1, num2, Real.Mult2(num1, num2));
        Console.WriteLine();
        //
        Console.ReadLine();
    }  
    //
    private static void pruebaDiv() {
        Console.WriteLine("Prueba de Dividir");
        Console.WriteLine();
        //
        string num1;
        string num2;
        Real.NumDecimales = 4;
        Real.MostrarResto = true;
        Console.WriteLine("Decimales: {0}", Real.NumDecimales);
        Console.WriteLine("Mostrar resto: {0}", Real.MostrarResto);
        Console.WriteLine();
        num1 = "10";
        num2 = "3";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "9";
        num2 = "4";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "155";
        num2 = "50";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "10000";
        num2 = "225";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "100";
        num2 = "2.25";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "10";
        num2 = "2.5";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        num1 = "100";
        num2 = "2.5";
        Console.WriteLine("{0} / {1} = {2}", num1, num2, Real.Div2(num1, num2));
        Console.WriteLine();
        //
        Console.ReadLine();
    }  
    private static void pruebaTodos() {
        pruebaDiv();
        pruebaMult();
        pruebaSuma();
        pruebaResta();
        pruebaPot();
    }  
}

 

El código de la estructura

//-----------------------------------------------------------------------------
// Multiplicar números usando cadenas de caracteres                    (10/Ago/04)
//
// Realizar operaciones con números de cualquier longitud
// Admite decimales                                                 (11/Ago/04)
//
// Operaciones soportadas:
//    Multiplicación, División, Potencia, Suma y Resta
//
// ©Guillermo 'guille' Som, 2004
//-----------------------------------------------------------------------------
using System;
 
namespace elGuille.Math{
    public struct Real{
        internal static string[] ad;
        public static int NumDecimales = 4;
        public static bool MostrarResto = false;
        public string Valor; // = "0";
        //
        public Real(string num)
        {
            int i = num.IndexOf(".");
            if(i > -1)
                if(num.Substring(i).Length > NumDecimales)
                    num = num.Substring(0, i) + "." + num.Substring(i+1, NumDecimales);
                else
                    num = num.Substring(0, i) + "." + num.Substring(i+1);
            Valor = num;
            ad = new string[1];
            ad[0] = num;
        }
        // sobrecarga de operadores
        public static Real operator +(Real r1, Real r2)
        {
            return new Real(Suma2(r1.Valor, r2.Valor)); 
        }
        public static Real operator +(Real r1, string r2)
        {
            return new Real(Suma2(r1.Valor, r2)); 
        }
        public static Real operator +(string r1, Real r2)
        {
            return new Real(Suma2(r1, r2.Valor)); 
        }
        //
        public static Real operator -(Real r1, Real r2)
        {
            return new Real(Resta2(r1.Valor, r2.Valor)); 
        }
        public static Real operator -(Real r1, string r2)
        {
            return new Real(Resta2(r1.Valor, r2)); 
        }
        public static Real operator -(string r1, Real r2)
        {
            return new Real(Resta2(r1, r2.Valor)); 
        }
        //
        public static Real operator *(Real r1, Real r2)
        {
            return new Real(Mult2(r1.Valor, r2.Valor)); 
        }
        public static Real operator *(Real r1, string r2)
        {
            return new Real(Mult2(r1.Valor, r2)); 
        }
        public static Real operator *(string r1, Real r2)
        {
            return new Real(Mult2(r1, r2.Valor)); 
        }
        //
        public static Real operator /(Real r1, Real r2)
        {
            return new Real(Div2(r1.Valor, r2.Valor)); 
        }
        public static Real operator /(Real r1, string r2)
        {
            return new Real(Div2(r1.Valor, r2)); 
        }
        public static Real operator /(string r1, Real r2)
        {
            return new Real(Div2(r1, r2.Valor)); 
        }
        //
        // convertir de Real a string
        public static implicit operator string(Real r1)
        {
            return r1.Valor;
        }
        // convertir de string a Real
        public static implicit operator Real(string r1)
        {
            return new Real(r1);
        }
        // convertir de Real a int
        public static explicit operator int(Real r1)
        {
            try{
                return int.Parse(r1.Valor);
            }catch{
                return 0;
            }
        }
        // Esta conversión no es necesaria si está la de long
//        // convertir de int a Real
//        public static implicit operator Real(int r1)
//        {
//            return new Real(Convert.ToString(r1));
//        }
        // convertir de long a Real
        public static implicit operator Real(long r1)
        {
            return new Real(Convert.ToString(r1));
        }
        // convertir de decimal a Real
        public static implicit operator Real(decimal r1)
        {
            string s = Convert.ToString(r1).Replace(",",".") ;
            return new Real(s);
        }
        // convertir de double a Real
        public static implicit operator Real(double r1)
        {
            string s = Convert.ToString(r1).Replace(",",".") ;
            return new Real(s);
        }
        //
        //
        public static bool operator <(Real r1, Real r2)
        {
            return Real.EsMenor(r1.Valor, r2.Valor); 
        }
        public static bool operator >(Real r1, Real r2)
        {
            return !Real.EsMenor(r1.Valor, r2.Valor); 
        }
        //
        public static bool operator ==(Real r1, Real r2)
        {
            return r1.Valor == r2.Valor; 
        }
        public static bool operator !=(Real r1, Real r2)
        {
            return r1.Valor != r2.Valor; 
        }
        //
        //
        public override string ToString()
        {
            return Valor;
        }
        //
        //
        public static bool EsMenor(string num1, string num2)
        {
            // comparar dos cadenas para ver cual es menor
            // deben tener el mismo número de digitos
            // antes y después del decimal
            int nDec1 = num1.IndexOf(".");
            int nDec2 = num2.IndexOf(".");
            int i = nDec1;
            if(i > -1){
                num1 = num1 + new string('0', NumDecimales);
                num1 = num1.Substring(0, i) + "." + num1.Substring(i+1, NumDecimales);
            }
            i = nDec2;
            if(i > -1){
                num2 = num2 + new string('0', NumDecimales); 
                num2 = num2.Substring(0, i) + "." + num2.Substring(i+1, NumDecimales);
            }
            // ajustar los dos tamaños al mayor
            if(nDec1 == -1 && nDec2 == -1){
                nDec1 = num1.Length;
                nDec2 = num2.Length;
            }
            if(nDec1 == -1) nDec1 = num1.Length;
            if(nDec2 == -1) nDec2 = num2.Length;
            if(nDec1 > nDec2)
                num2 = (new string('0', nDec1) + num2);
            if(nDec2 > nDec1)
                num1 = (new string('0', nDec2) + num1);
            //
            if(string.Compare(num1, num2) < 0)
                return true;
            else
                return false;
        }
        //
        private static string miDiv2(string num1, string num2, int decAct) 
        {
            string res = num1;
            int n = 0;
            if( num2.Length < num1.Length ){
                num2 = (new string('0', num1.Length) + num2).Substring(num2.Length, num1.Length);
            }
            while(true){
                res = miResta2(res, num2);
                n += 1;
                if( res == "0" || string.Compare(res, num2)< 0 ) break;
            }
            res = quitarCeros(res);
            if( res != "0" ){
                if( decAct < NumDecimales ){
                    decAct += 1;
                    res = miDiv2(res + "0", num2, decAct);
                    // quitar los puntos que haya
                    res = res.Replace(".", "");
                    return n.ToString() + "." + res;
                }else{
                    // si queda un resto mostrarlo con :
                    // (o bien no mostrarlo)
                    if( MostrarResto ){
                        return n.ToString() + ":" + res;
                    }else{
                        return n.ToString();
                    }
                }
            }else{
                return n.ToString();
            }
        }  
        public static string Div2(string num1, string num2) {
            // Para dividir dos números:
            // Se leva restando al dividendo el divisor hasta que
            // el resto sea cero o menor que el divisor
            int decAct = 0;
            //
            int nDec1 = 0;
            int nDec2 = 0;
            int dec1 = num1.IndexOf(".");
            int dec2 = num2.IndexOf(".");
            if( dec1 > -1 ){
                num1 = quitarCerosFinales(num1);
                nDec1 = num1.Substring(dec1 + 1).Length;
                num1 = num1.Replace(".", "");
            }
            if( dec2 > -1 ){
                num2 = quitarCerosFinales(num2);
                nDec2 = num2.Substring(dec2 + 1).Length;
                num2 = num2.Replace(".", "");
            }
            if( nDec1 > 0 ){
                num2 = num2 + new string('0', nDec1);
            }
            if( nDec2 > 0 ){
                num1 = num1 + new string('0', nDec2);
            }
            //
            return miDiv2(num1, num2, decAct);
        }  
        //
        public static string PotN(string num1, string elevado) {
            int i;
            //
            // si el exponente tiene decimales, quitárselo
            i = elevado.IndexOf(".");
            if( i > -1 ){
                elevado = elevado.Substring(0, i);
            }
            //
            if( elevado == "0" ){
                return "1";
            }else if( elevado == "1" ){
                return num1;
            }
            if( num1 == "1" ){
                return "1";
            }else if( num1 == "0" ){
                return "0";
            }
            //
            i = Convert.ToInt32(elevado);
            string[] p = new string[i];
            for(int k = 0; k < i; k++){
                p[k] = num1;
            }
            return Mult2(p);
        }  
        //
        public static string Mult2( params string[] nums) {
            string total = nums[0];
            for(int i= 1; i< nums.Length; i++){
                string n1 = nums[i];
                total = Mult2(total, n1);
            }
            //
            return total;
        }  
        //
        public static string Mult2(string num1, string num2) {
            //
            // Comprobar si alguno de los números tiene decimales        (11/Ago/04)
            int nDec = 0;
            //
            int dec1 = num1.IndexOf(".");
            int dec2 = num2.IndexOf(".");
            if( dec1 > -1 ){
                nDec = num1.Substring(dec1 + 1).Length;
                num1 = num1.Replace(".", "");
            }
            if( dec2 > -1 ){
                nDec += num2.Substring(dec2 + 1).Length;
                num2 = num2.Replace(".", "");
            }
            //
            // Poner el más largo como primer número
            if( num2.Length > num1.Length ){
                Swap(ref num1, ref num2);
            }
            //
            // El número de operaciones necesarias
            // será la cantidad de cifras del más pequeño
            ad = new string[num2.Length];
            int n = -1;
            string resto = "0";
            string res = "";
            //
            // Multiplicar formando filas con los resultados (al estilo manual)
            for(int i= num2.Length - 1; i>= 0; i--){
                n += 1;
                ad[n] = "";
                // Añadir espacios a la derecha según la cifra (fila) que se procese
                for(int k= 1; k<= n; k++){
                    ad[n] += " ";
                }
                string c1 = num2.Substring(i, 1);
                // Para simplificar las cosas
                // se comprueba si se multiplicará por ceo o por uno
                // de forma que no sea necesario hacer estas operaciones
                if( c1 == "0" ){
                    ad[n] = new string('0', num1.Length) + ad[n];
                }else if( c1 == "1" ){
                    ad[n] = num1 + ad[n];
                }else{
                    for(int j= num1.Length - 1; j>= 0; j--){
                        string c2 = num1.Substring(j, 1);
                        res = (Convert.ToInt32("0" + c1) * Convert.ToInt32("0" + c2) + Convert.ToInt32(resto)).ToString();
                        ad[n] = res.Substring(res.Length - 1, 1) + ad[n];
                        if( res.Length - 1 < 1 ){
                            resto = "0";
                        }else{
                            resto = res.Substring(0, res.Length - 1);
                        }
                    }
                    if( resto != "0" ){
                        ad[n] = resto + ad[n];
                        resto = "0";
                    }
                }
            }
            //
            res = sumarFilas();
            if( nDec > 0 ){
                if( NumDecimales == 0 ){
                    res = res.Substring(0, res.Length - nDec);
                }else{
                    resto = res.Substring(res.Length - nDec);
                    if( resto.Length > NumDecimales ){
                        resto = resto.Substring(0, NumDecimales);
                    }
                    res = res.Substring(0, res.Length - nDec) + "." + quitarCerosFinales(resto);
                }
            }
            return res;
        }  
        //
        public static string Suma2( params string[] nums) {
            //
            ad = new string[nums.Length];
            for(int i= 0; i< nums.Length; i++){
                ad[i] = nums[i];
            }
            //
            return sumarFilas();
        }  
        //
        public static string Suma2(string num1, string num2) {
            ad = new string[2];
            //
            int nDec = 0;
            int nDec1 = 0;
            int nDec2 = 0;
            int dec1 = num1.IndexOf(".");
            int dec2 = num2.IndexOf(".");
            if( dec1 > -1 ){
                num1 = quitarCerosFinales(num1);
                nDec1 = num1.Substring(dec1 + 1).Length;
                num1 = num1.Replace(".", "");
            }
            if( dec2 > -1 ){
                num2 = quitarCerosFinales(num2);
                nDec2 = num2.Substring(dec2 + 1).Length;
                num2 = num2.Replace(".", "");
            }
            if( nDec1 > 0 ){
                num2 = num2 + new string('0', nDec1);
            }
            if( nDec2 > 0 ){
                num1 = num1 + new string('0', nDec2);
            }
            nDec = nDec1 + nDec2;
            //
            ad[0] = num1;
            ad[1] = num2;
            //
            //Return sumarFilas()
            //
            string res = sumarFilas();
            string resto = "";
            if( nDec > 0 ){
                if( NumDecimales == 0 ){
                    res = res.Substring(0, res.Length - nDec);
                }else{
                    resto = res.Substring(res.Length - nDec);
                    if( resto.Length > NumDecimales ){
                        resto = resto.Substring(0, NumDecimales);
                    }
                    res = res.Substring(0, res.Length - nDec) + "." + quitarCerosFinales(resto);
                }
            }
            return res;
        }  
        //
        public static string Resta2( params string[] nums) {
            string total = nums[0];
            for(int i= 1; i<= nums.Length - 1; i++){
                string n1 = nums[i];
                //total = Resta2(total, n1)
                total = miResta2(total, n1);
            }
            //
            return total;
        }  
        //
        private static string miResta2(string num1, string num2) {
            // usar esta función para cálculos internos en los que no se deben quitar
            // los ceros del principio del número
            ad = new string[2];
            //
            int nDec = 0;
            int nDec1 = 0;
            int nDec2 = 0;
            int dec1 = num1.IndexOf(".");
            int dec2 = num2.IndexOf(".");
            if( dec1 > -1 ){
                num1 = quitarCerosFinales(num1);
                nDec1 = num1.Substring(dec1 + 1).Length;
                num1 = num1.Replace(".", "");
            }
            if( dec2 > -1 ){
                num2 = quitarCerosFinales(num2);
                nDec2 = num2.Substring(dec2 + 1).Length;
                num2 = num2.Replace(".", "");
            }
            if( nDec1 > 0 ){
                num2 = num2 + new string('0', nDec1);
            }
            if( nDec2 > 0 ){
                num1 = num1 + new string('0', nDec2);
            }
            nDec = nDec1 + nDec2;
            //
            ad[0] = num1;
            ad[1] = num2;
            //
            //Return restar2Filas()
            //
            string res = restar2Filas();
            string resto = "";
            if( nDec > 0 ){
                if( NumDecimales == 0 ){
                    res = res.Substring(0, res.Length - nDec);
                }else{
                    resto = res.Substring(res.Length - nDec);
                    if( resto.Length > NumDecimales ){
                        resto = resto.Substring(0, NumDecimales);
                    }
                    res = res.Substring(0, res.Length - nDec) + "." + quitarCerosFinales(resto);
                }
            }
            return res;
        }  
        //
        public static string Resta2(string num1, string num2) {
            return quitarCeros(miResta2(num1, num2));
            //
        }  
        //
        private static string sumarFilas() {
            int m = 0;
            int n = ad.Length - 1;
            //
            // m será el número de mayor longitud
            for(int k= 0; k<= n; k++){
                if( ad[k].Length > m ) m = ad[k].Length;
            }
            //
            // sumar las filas obtenidas
            string resto = "0";
            string total = "";
            string res = "";
            //
            for(int k= 0; k<= n; k++){
                ad[k] = (new string(' ', m) + ad[k]).Substring(ad[k].Length, m);
            }
            for(int k= m - 1; k>= 0; k--){
                res = resto;
                for(int i= 0; i<= n; i++){
                    res = (Convert.ToInt32(res) + Convert.ToInt32("0" + ad[i].Substring(k, 1))).ToString();
                }
                total = res.Substring(res.Length - 1, 1) + total;
                if( res.Length - 1 < 1 ){
                    resto = "0";
                }else{
                    resto = res.Substring(0, res.Length - 1);
                }
            }
            if( resto != "0" ){
                total = resto + total;
            }
            //
            return total;
        }  
        //
        private static string restar2Filas() {
            int m = 0;
            int n = ad.Length - 1;
            //
            for(int k= 0; k<= n; k++){
                if( ad[k].Length > m ) m = ad[k].Length;
            }
            //
            // restar las filas obtenidas
            string resto = "0";
            string total = "";
            string res = "";
            //
            for(int k= 0; k<= n; k++){
                ad[k] = (new string('0', m) + ad[k]).Substring(ad[k].Length, m);
            }
            for(int k= m - 1; k>= 0; k--){
                res = (Convert.ToInt32("0" + ad[0].Substring(k, 1)) - (Convert.ToInt32("0" + ad[1].Substring(k, 1)) + Convert.ToInt32(resto))).ToString();
                if( Convert.ToInt32(res) < 0 ){
                    res = (Convert.ToInt32(res) + 10).ToString();
                    res = "1" + res;
                }
                total = res.Substring(res.Length - 1, 1) + total;
                if( res.Length - 1 < 1 ){
                    resto = "0";
                }else{
                    resto = res.Substring(0, res.Length - 1);
                }
            }
            if( resto != "0" ){
                total = resto + total;
            }
            //
            return total;
        }  
        //
        public static void Swap(ref string n1, ref string n2) {
            string t = n1;
            n1 = n2;
            n2 = t;
        }  
        //
        private static string quitarCeros(string num) {
            //
            // Si tiene varios ceros, dejar sólo uno
            while( num.StartsWith("0")){
                if( num == "0" ) break;
                num = num.Substring(1);
            }
            return num;
        }  
        private static string quitarCerosFinales(string num) {
            //
            // Si tiene varios ceros, dejar sólo uno
            while( num.EndsWith("0")){
                if( num == "0" ) break;
                num = num.Substring(0, num.Length - 1);
            }
            return num;
        }  
    }
}

 


El código para Visual Basic 6.0 (o anteriores a VB .NET)

El código de VB6 es el de la versión anterior.

 


la Luna del Guille o... el Guille que está en la Luna... tanto monta...