【问题标题】:Using the mpz_powm functions from the GMP/MPIR libraries with negative exponents使用具有负指数的 GMP/MPIR 库中的 mpz_powm 函数
【发布时间】:2012-06-24 21:03:18
【问题描述】:

请考虑以下代码:

mpz_t x, n, out;

mpz_init_set_ui(x, 2UL);
mpz_init_set_ui(n, 7UL);
mpz_init(out);

mpz_invert(out, x, n);
gmp_printf ("%Zd\n", out);//prints 4. 2 * 4 (mod 7) = 1. OK

mpz_powm_ui(out, x, -1, n);//prints 1. 2 * 1 (mod 7) = 2. How come?
gmp_printf ("%Zd\n", out);

mpz_clear(x);
mpz_clear(n);
mpz_clear(out);

我无法理解 mpz_powm 函数如何处理负指数,尽管根据文档,它应该支持它们。我希望将一个数字提高到 -1 模 n 相当于将它取反模 n。我在这里错过了什么?

【问题讨论】:

    标签: c++ primes gmp negative-number


    【解决方案1】:

    尝试将 -1 设为 有符号 数。换句话说,不要使用无符号接口,而是创建一个值为 -1 的真正 bignum。

    即:

    #include <gmpxx.h>
    #include <iostream>
    
    int main()
    {
        mpz_class n(7), k(2), res;
        mpz_powm(res.get_mpz_t(), k.get_mpz_t(), mpz_class(-1).get_mpz_t(), n.get_mpz_t());
        std::cout << res << std::endl;
    }
    

    打印:

    4
    

    【讨论】:

    • Ufff... 抱歉。这是一个复制/粘贴出错的问题。不幸的是,即使我删除了它,行为也是一样的。
    • 确实,mpz_powm_ui 的声明方式存在问题。我刚刚注意到一个明显的事实,即 exp 参数在 gmp.h 中被声明为 unsigned long。我会问 GMP/MPIR 开发人员为什么会这样。谢谢你帮我弄清楚。
    【解决方案2】:

    问题是由mpz_powm_ui函数的声明方式引起的:

    void mpz_powm_ui (mpz t rop, mpz t base, unsigned long int exp, mpz t mod)
    

    也许这是一个文档错误,因为 exp 总是为正数。

    【讨论】:

    • 末尾的 _ui 很好地表明它需要一个无符号整数。
    • 是的,确实如此。该文档有点误导,因为它没有为mpz_powm 和mpz_powm_ui 提供不同的描述。无论如何,我很高兴我终于设法找出导致我的应用程序产生奇怪结果的原因。
    • 是的,它可能应该被拆分出来,因为行为有点不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多