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í?
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 unBigInteger
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, dondea % b
devuelve un valor con el mismo signo queb
.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: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 sumap
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.