Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 求Z(n)中x的乘法逆,扩展欧氏算法_C_Algorithm_Gmp - Fatal编程技术网

C 求Z(n)中x的乘法逆,扩展欧氏算法

C 求Z(n)中x的乘法逆,扩展欧氏算法,c,algorithm,gmp,C,Algorithm,Gmp,我试图用GMP库找到x的乘法逆;我知道有一个内置函数,但我想自己编写。 这是我的扩展欧几里德算法实现: void extended_euclides(mpz_t r,mpz_t x,mpz_t y,mpz_t a, mpz_t b){ mpz_t r_2,r_1,x_2,x_1,y_2,y_1,q,tmp; mpz_inits(r,x,y,NULL); mpz_init_set(r_2,a); mpz_init_set(r_1,b); mpz_init

我试图用GMP库找到x的乘法逆;我知道有一个内置函数,但我想自己编写。
这是我的扩展欧几里德算法实现:

void extended_euclides(mpz_t r,mpz_t x,mpz_t y,mpz_t a, mpz_t b){
    mpz_t r_2,r_1,x_2,x_1,y_2,y_1,q,tmp;

    mpz_inits(r,x,y,NULL);

    mpz_init_set(r_2,a);
    mpz_init_set(r_1,b);
    mpz_init_set_ui(x_2,1);
    mpz_init_set_ui(y_2,0);
    mpz_init_set_ui(x_1,0);
    mpz_init_set_ui(y_1,1);
    mpz_init_set_ui(q,0);
    mpz_init_set_ui(tmp,0);

    do{
        mpz_fdiv_qr(q,r,r_2,r_1);   
        //x
        mpz_mul(tmp,q,x_1);
        mpz_sub(x,x_2,tmp);
        //y
        mpz_mul(tmp,q,y_1);
        mpz_sub(y,y_2,tmp);

        mpz_set(x_2,x_1);
        mpz_set(x_1,x);     

        mpz_set(y_2,y_1);
        mpz_set(y_1,y);

        mpz_set(r_2,r_1);
        mpz_set(r_1,r);
    }while(mpz_cmp_ui(r,0)!=0);

    mpz_set(r,r_1);
    mpz_set(x,x_2);
    mpz_set(y,y_2);

    mpz_clears(r_2,r_1,x_2,y_2,x_1,y_1,q,tmp,NULL);
}
它适用于所有小数字和一些大数字,但不适用于所有数字,我不知道为什么。不起作用的示例编号:

a=994934854363575092942994436068793093643611893389896126764674829386592836164617544660927853380679690367562437995066704174322591642123562781847156006846186608672153850717131150491084706497192710261706218845591506450899256227024915666155869840788520287764003390626292517674744128
b=202287573793610924311033969010234326099

如果我将b更改为:

b=202287573793610924311033969010234326199

它工作正常(我将第一个0从右侧更改为1);我得到的结果是:

-26280231501456618600907242915048902345641123248519760433640466576442417863717426872152822551963711381875692705631908417947744118343264058883575032407104944563964379952360665811485067983902142081479280567331029833439916753095352323590334646483487331833771039796532851685

正确的结果,由GMP函数计算并由me在等式
b*b^-1中检查≡ 1模块(a)
,是:

73213253934900890693392193153744191297970770141363663310343628101504182766824580197371257112553772665618056230236107226590446902102892363759587985360547611421622677412736477048763762348558009314571492010697728385682299892488548124124487689455428842295356848484548945199287685431157024743


如果a和b是共素数,扩展欧几里德算法会发现x和y

x a + y b == 1
但是x或y可能是负数。对于y=b模a的逆

if y < 0 then y = y + a,
如果y<0,则y=y+a,
这将把y转换成模a的适当值(注意我之前的评论)

wiki示例发现t=模n的逆,并具有相同的检查:

if t < 0 then t = t + n 
如果t<0,则t=t+n

在坏情况下,您会得到什么输出?那么预期的输出是什么?@Bartek-如果你得到一个否定的结果,在结果中加上{a}。根据前5位数字,它似乎工作正常。@rcgldr,a=(p-1)(q-1),p,q是素数,b我选择与a互质。我确信我在问题中粘贴的a中的b是反向的。GMP函数返回正确的结果。我不明白为什么我的实现有时会返回正确的结果和另一个inpropper,当GMP函数返回相同数字的正确结果时。@rcgldr,而不是您:),请将其作为答案。@Bartek-添加了答案,删除了之前的注释。稍后将删除此评论。