Swift与Python的模运算差异
我试图将模块化逆运算从Python移植到Swift,而我的模块化运算产生了不同的结果我想知道是否有人能指出为什么我会得到不同的结果?我正在使用BInt库 PYTHON代码:Swift与Python的模运算差异,python,swift,modulo,modular-arithmetic,Python,Swift,Modulo,Modular Arithmetic,我试图将模块化逆运算从Python移植到Swift,而我的模块化运算产生了不同的结果我想知道是否有人能指出为什么我会得到不同的结果?我正在使用BInt库 PYTHON代码: def inverse(x, p): """ Calculate the modular inverse of x ( mod p ) the modular inverse is a number such that: (inverse(x, p) * x) % p == 1 you could think o
def inverse(x, p):
"""
Calculate the modular inverse of x ( mod p )
the modular inverse is a number such that:
(inverse(x, p) * x) % p == 1
you could think of this as: 1/x
"""
inv1 = 1
inv2 = 0
print "first x = %d" % x
print "first p = %d" % p
while p != 1 and p!=0:
inv1, inv2 = inv2, inv1 - inv2 * (x / p)
print "inv1 = %d" % inv1
print "inv2 = %d" % inv2
x, p = p, x % p
print "x = %d" % x
print "p = %d" % p
return inv2
func inverse(b: BInt, n: BInt) -> BInt {
var inv1 = BInt(1)
var inv2 = BInt(0)
var p = n
var x = b
print("first x = \(x)")
print("first p = \(p)")
while p != 1 && p != 0 {
var temp = inv2
inv2 = inv1 - inv2 * (x/p)
inv1 = temp
print("inv1 = \(inv1)")
print("inv2 = \(inv2)")
temp = p
p = x % p
x = temp
print("x = \(x)")
print("p = \(p)")
}
return inv2
}
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = 81292460333046534861896783477920749818876442289795948381273441455000762414306
inv1 = 1
inv2 = -1
x = 81292460333046534861896783477920749818876442289795948381273441455000762414306
p = 34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = -1
inv2 = 3
x = 34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = -34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = 1
inv2 = 3
x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
inv1 = 3
inv2 = 7
x = 12293202524507213738548380416386433750089357538106717064905156349184617899592
p = -9913223855255233084577440697994290534214827299631181528373829854538836458173
SWIFT代码:
def inverse(x, p):
"""
Calculate the modular inverse of x ( mod p )
the modular inverse is a number such that:
(inverse(x, p) * x) % p == 1
you could think of this as: 1/x
"""
inv1 = 1
inv2 = 0
print "first x = %d" % x
print "first p = %d" % p
while p != 1 and p!=0:
inv1, inv2 = inv2, inv1 - inv2 * (x / p)
print "inv1 = %d" % inv1
print "inv2 = %d" % inv2
x, p = p, x % p
print "x = %d" % x
print "p = %d" % p
return inv2
func inverse(b: BInt, n: BInt) -> BInt {
var inv1 = BInt(1)
var inv2 = BInt(0)
var p = n
var x = b
print("first x = \(x)")
print("first p = \(p)")
while p != 1 && p != 0 {
var temp = inv2
inv2 = inv1 - inv2 * (x/p)
inv1 = temp
print("inv1 = \(inv1)")
print("inv2 = \(inv2)")
temp = p
p = x % p
x = temp
print("x = \(x)")
print("p = \(p)")
}
return inv2
}
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = 81292460333046534861896783477920749818876442289795948381273441455000762414306
inv1 = 1
inv2 = -1
x = 81292460333046534861896783477920749818876442289795948381273441455000762414306
p = 34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = -1
inv2 = 3
x = 34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = -34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = 1
inv2 = 3
x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
inv1 = 3
inv2 = 7
x = 12293202524507213738548380416386433750089357538106717064905156349184617899592
p = -9913223855255233084577440697994290534214827299631181528373829854538836458173
Python结果:
def inverse(x, p):
"""
Calculate the modular inverse of x ( mod p )
the modular inverse is a number such that:
(inverse(x, p) * x) % p == 1
you could think of this as: 1/x
"""
inv1 = 1
inv2 = 0
print "first x = %d" % x
print "first p = %d" % p
while p != 1 and p!=0:
inv1, inv2 = inv2, inv1 - inv2 * (x / p)
print "inv1 = %d" % inv1
print "inv2 = %d" % inv2
x, p = p, x % p
print "x = %d" % x
print "p = %d" % p
return inv2
func inverse(b: BInt, n: BInt) -> BInt {
var inv1 = BInt(1)
var inv2 = BInt(0)
var p = n
var x = b
print("first x = \(x)")
print("first p = \(p)")
while p != 1 && p != 0 {
var temp = inv2
inv2 = inv1 - inv2 * (x/p)
inv1 = temp
print("inv1 = \(inv1)")
print("inv2 = \(inv2)")
temp = p
p = x % p
x = temp
print("x = \(x)")
print("p = \(p)")
}
return inv2
}
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = 81292460333046534861896783477920749818876442289795948381273441455000762414306
inv1 = 1
inv2 = -1
x = 81292460333046534861896783477920749818876442289795948381273441455000762414306
p = 34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = -1
inv2 = 3
x = 34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = -34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = 1
inv2 = 3
x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
inv1 = 3
inv2 = 7
x = 12293202524507213738548380416386433750089357538106717064905156349184617899592
p = -9913223855255233084577440697994290534214827299631181528373829854538836458173
Swift结果:
def inverse(x, p):
"""
Calculate the modular inverse of x ( mod p )
the modular inverse is a number such that:
(inverse(x, p) * x) % p == 1
you could think of this as: 1/x
"""
inv1 = 1
inv2 = 0
print "first x = %d" % x
print "first p = %d" % p
while p != 1 and p!=0:
inv1, inv2 = inv2, inv1 - inv2 * (x / p)
print "inv1 = %d" % inv1
print "inv2 = %d" % inv2
x, p = p, x % p
print "x = %d" % x
print "p = %d" % p
return inv2
func inverse(b: BInt, n: BInt) -> BInt {
var inv1 = BInt(1)
var inv2 = BInt(0)
var p = n
var x = b
print("first x = \(x)")
print("first p = \(p)")
while p != 1 && p != 0 {
var temp = inv2
inv2 = inv1 - inv2 * (x/p)
inv1 = temp
print("inv1 = \(inv1)")
print("inv2 = \(inv2)")
temp = p
p = x % p
x = temp
print("x = \(x)")
print("p = \(p)")
}
return inv2
}
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = 81292460333046534861896783477920749818876442289795948381273441455000762414306
inv1 = 1
inv2 = -1
x = 81292460333046534861896783477920749818876442289795948381273441455000762414306
p = 34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = -1
inv2 = 3
x = 34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
first x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
first p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
inv1 = 0
inv2 = 1
x = 115792089237316195423570985008687907853269984665640564039457584007908834671663
p = -34499628904269660561674201530767158034393542375844615658184142552908072257357
inv1 = 1
inv2 = 3
x = -34499628904269660561674201530767158034393542375844615658184142552908072257357
p = 12293202524507213738548380416386433750089357538106717064905156349184617899592
inv1 = 3
inv2 = 7
x = 12293202524507213738548380416386433750089357538106717064905156349184617899592
p = -9913223855255233084577440697994290534214827299631181528373829854538836458173
也许您应该提到您在Swift中使用的大整数库,
BInt
不是标准库类型。快速实验:Swift中的-2%5
是什么-2还是3?如果它是-2,这可能解释了这种差异(虽然确切地说这并不明显)。-2%5=-2
在Swift:,但我不知道大整数库是如何计算的。根据PARI/GP,对于模数1157920892373161954235709850086879078532699846656640564039457584007908834671663
,模数1157920892373161955667675667439354237584461568184142552908072257357
的模逆是3773201645528448156445462841640885215622248208227004528229572406827
,我在Swift实现中,在x=temp
之后添加了如果p<0{p+=x}
,那么viola的结果与Python相同。我不能说这是否解释了余数与模的差异,但我会做更多的测试用例,如果我们没有完全解决这个问题,我们似乎走上了正确的道路