trabajando con números increíblemente grandes en .NET

Estoy tratando de resolver los problemas en projecteuler.net pero sigo encontrando un par de problemas.

El primero es una cuestión de almacenar grandes cantidades de elementos en una List . Sigo recibiendo OutOfMemoryException al almacenar grandes cantidades en la lista.

Ahora admito que no podría estar haciendo estas cosas de la mejor manera pero, ¿hay alguna forma de definir cuánta memoria puede consumir la aplicación?

Por lo general, se cuelga cuando llego a 100,000,000 de elementos: S

En segundo lugar, algunas de las preguntas requieren la adición de números masivos. Utilizo el tipo de datos ulong, donde creo que el número va a ser muy grande, pero aún así me las arreglé para envolver el int más extenso y obtener números negativos.

¿Tiene algún consejo para trabajar con números increíblemente grandes?

    Considere System.Numerics.BigInteger .

    Necesitará usar una clase numérica grande que use algunos principios matemáticos básicos para dividir estas operaciones. Esta implementación de una biblioteca C # BigInteger en CodePoject parece ser la más prometedora. El artículo tiene algunas buenas explicaciones de cómo funcionan las operaciones con números masivos, también.

    Ver también: enteros grandes en C #

    En lo que respecta al Proyecto Euler, es posible que estés ladrando al árbol equivocado si estás golpeando excepciones de OutOfMemory. De su sitio web:

    Cada problema ha sido diseñado de acuerdo con una “regla de un minuto”, lo que significa que, aunque puede llevar varias horas diseñar un algoritmo exitoso con problemas más difíciles, una implementación eficiente permitirá obtener una solución en una computadora de modesta potencia. menos de un minuto

    Como dijo el usuario Jakers, si estás usando Big Numbers, probablemente lo estés haciendo mal.

    De los problemas de ProjectEuler que he hecho, ninguno ha requerido matemática de gran número hasta ahora. Se trata más de encontrar el algoritmo adecuado para evitar números grandes.

    ¿Quieres pistas? Publique aquí, y podríamos tener un hilo de Euler interesante iniciado.

    Supongo que esto es C #? F # ha construido formas de manejar ambos problemas (tipo BigInt y secuencias perezosas).

    Puedes usar ambas técnicas F # de C #, si quieres. El tipo BigInt se puede utilizar razonablemente desde otros idiomas si agrega una referencia al ensamblaje F # central.

    Las secuencias diferidas son básicamente simples enumeradores amigables a la syntax. Poner 100.000,000 de elementos en una lista no es un gran plan, por lo que debe reconsiderar sus soluciones para evitarlo. Si no necesita mantener la información a su scope, ¡deséchela! Si es más barato recalcularlo que almacenarlo, ¡deséchelo!

    Ver las respuestas en este hilo . Probablemente necesite usar una de las librerías / clases de enteros grandes de terceros disponibles o espere C # 4.0 que incluirá un tipo de datos BigInteger nativo.

    En cuanto a la definición de cuánta memoria usará una aplicación, puede verificar la memoria disponible antes de realizar una operación utilizando la clase MemoryFailPoint .

    Esto le permite preasignar memoria antes de hacer la operación, por lo que puede verificar si una operación fallará antes de ejecutarla.

    No necesita usar BigInteger. Puede hacer este evento con un conjunto de números de cadena.

     class Solution { static void Main(String[] args) { int n = 5; string[] unsorted = new string[6] { "3141592653589793238","1", "3", "5737362592653589793238", "3", "5" }; string[] result = SortStrings(n, unsorted); foreach (string s in result) Console.WriteLine(s); Console.ReadLine(); } static string[] SortStrings(int size, string[] arr) { Array.Sort(arr, (left, right) => { if (left.Length != right.Length) return left.Length - right.Length; return left.CompareTo(right); }); return arr; } } 
     string Add(string s1, string s2) { bool carry = false; string result = string.Empty; if (s1.Length < s2.Length) s1 = s1.PadLeft(s2.Length, '0'); if(s2.Length < s1.Length) s2 = s2.PadLeft(s1.Length, '0'); for(int i = s1.Length-1; i >= 0; i--) { var augend = Convert.ToInt64(s1.Substring(i,1)); var addend = Convert.ToInt64(s2.Substring(i,1)); var sum = augend + addend; sum += (carry ? 1 : 0); carry = false; if(sum > 9) { carry = true; sum -= 10; } result = sum.ToString() + result; } if(carry) { result = "1" + result; } return result; }