es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Diferencia en los cálculos de BigInteger en C# y Python

Hola, estoy intentando hacer algunos cálculos matemáticos con BigIntegers. Estoy convirtiendo un código de Python a C# y los resultados que obtengo en C# son diferentes a los de Python.

Aquí está el código en C#

BigInteger two = BigInteger.Parse("2");
BigInteger p = BigInteger.Parse("21888242871839275222246405745257275088548364400416034343698204186575808495617");
BigInteger s1 = BigInteger.Parse("14132513739920849383792069751007754351800355055139761101807090020635929082500");
BigInteger s2 = BigInteger.Parse("16855243938201383859390618757402894710090949997910827510175914850401122313679");

BigInteger result = BigInteger.ModPow((s1-s2) % p, p - two, p);

El resultado en C# es -172003418180865315706632281401673997799012376343679936021783339603882732265

En Python

def calculateResult():
    two = 2
    p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
    s1 = 14132513739920849383792069751007754351800355055139761101807090020635929082500
    s2 = 16855243938201383859390618757402894710090949997910827510175914850401122313679
    print(f'RESULT: { pow((s1 - s2) % p, p - two, p) }')

El resultado en Python es 21716239453658409906539773463855601090749352024072354407676420846971925763352

¿Alguien sabe qué está pasando aquí?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el código C# produce un resultado diferente al código Python al realizar operaciones matemáticas con BigInteger. Esto puede deberse a varios factores, como diferencias de versión o detalles de implementación. Sin embargo, un problema potencial en este caso específico es que C# y Python manejan la división de enteros de manera diferente.

    En el código C#, se evalúa primero la expresión (s1-s2) % p, lo cual produce un BigInteger negativo debido a que el resultado es menor que 0. En este caso, el operador % devuelve el resto de la división de los valores absolutos y preserva el signo del dividendo. Esto es diferente en Python, donde a % b devuelve un valor con el mismo signo que b.

    Para solucionar este problema en el código C#, una opción es usar el método Math.DivRem en lugar de %, el cual devuelve tanto el cociente como el resto de una división. Por ejemplo:

    BigInteger resto;
    BigInteger cociente = BigInteger.DivRem(s1 - s2, p, out resto);
    if (resto.Sign < 0)
    {
        resto += p;
    }
    BigInteger resultado = BigInteger.ModPow(resto, p - dos, p);
    

    Este código utiliza DivRem para calcular el cociente y el resto de la división (s1 - s2) / p, y luego verifica si el resto es negativo. Si lo es, se le suma p para hacerlo positivo, ya que se espera que el resultado de la exponenciación sea positivo.

    Al usar DivRem y manejar los restos negativos correctamente, el código C# debería producir el mismo resultado que el código Python en este caso.

Comments are closed.