Math 如何计算晶体中的模幂?
我想用水晶计算Math 如何计算晶体中的模幂?,math,modulo,crystal-lang,exponentiation,Math,Modulo,Crystal Lang,Exponentiation,我想用水晶计算1_299_709**1_300_751%104_729 在Python中,pow函数允许将模作为第三个参数传递: ❯ python >>>战俘(1_299_709、1_300_751、104_729) 90827 在Ruby中,相同的: ❯ 内部评级 irb(主):001:0>1_299_709.功率(1_300_751,104_729) => 90827 但在Crystal中,似乎没有这样的功能,自然地,使用**操作符会很快溢出: ❯ crystal eval "1_299
1_299_709**1_300_751%104_729
在Python中,pow
函数允许将模作为第三个参数传递:
❯ python
>>>战俘(1_299_709、1_300_751、104_729)
90827
在Ruby中,相同的:
❯ 内部评级
irb(主):001:0>1_299_709.功率(1_300_751,104_729)
=> 90827
但在Crystal中,似乎没有这样的功能,自然地,使用**
操作符会很快溢出:
❯ crystal eval "1_299_709 ** 1_300_751 % 104_729"
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/lib/crystal/int.cr:0:9 in '**'
from /eval:1:1 in '__crystal_main'
from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ???
如何计算晶体中的模幂
编辑:为了澄清,我已经在使用
BigInt
,但这不起作用。为了简单起见,我从最小工作示例中删除了BigInt
以下Python代码包含我的程序中的实际数字:
>>战俘(535831157736167294219578148707554849804042982901134400501331255090818409243、28948022309329048589274625271976963317496166410141009864396001977208667916、115792089237316195423570985008687905326998465640564039457584007908834671663)
75711134420273723792089656449854389054866833762486990555172221523628676983696
它易于执行并返回正确的结果。Ruby也一样:
irb(main):001:0>53583115773616729421957814870755484980404298242901134400501331255090818409243.pow(2894802230932904885589274625217197696331749616641014100986
4396001977208667916, 115792089237316195423570985008687907853269984665640564039457584007908834671663)
=> 75711134420273723792089656449854389054866833762486990555172221523628676983696
但是,Crystal:
a = BigInt.new 53583115773616729421957814870755484980404298242901134400501331255090818409243
e = BigInt.new 28948022309329048855892746252171976963317496166410141009864396001977208667916
p = BigInt.new 115792089237316195423570985008687907853269984665640564039457584007908834671663
y = a ** e % p # overflows with and without BigInt
其结果是:
gmp: overflow in mpz type
Program received and didn't handle signal IOT (6)
如何计算晶体中如此巨大的模幂
编辑:提交一个问题以确保它不是一个bug:如Github问题中所述,这可以通过从
gmp
绑定mpz\u powm\u sec
轻松避免:
这很简单:
require "big/big_int"
a = BigInt.new "53583115773616729421957814870755484980404298242901134400501331255090818409243"
e = BigInt.new "28948022309329048855892746252171976963317496166410141009864396001977208667916"
p = BigInt.new "115792089237316195423570985008687907853269984665640564039457584007908834671663"
@[Link("gmp")]
lib LibGMP
fun mpz_powm_sec = __gmpz_powm_sec(rop : MPZ*, base : MPZ*, exp : MPZ*, mod : MPZ*)
end
#y = a ** e % p
y = BigInt.new
LibGMP.mpz_powm_sec(y, a, e, p)
puts y
# > 75711134420273723792089656449854389054866833762486990555172221523628676983696