【问题标题】:Issue with a while loop using GMP使用 GMP 的 while 循环问题
【发布时间】:2020-02-15 15:57:50
【问题描述】:

我正在尝试使用 GMP 库 对扩展欧几里得算法进行编码,因为我使用的数字很大。我的算法是基本算法,仅适用于 GMP 数字。

但是我的 while 循环有问题。下面的代码是我的算法的一个可重现的可重复示例。我更改循环的内容只是为了测试。

void euclid(mpz_t a, mpz_t b){


mpz_t r1, r2, u1, u2, v1, v2;

mpz_init_set_ui(u1, 1);
mpz_init_set_ui(v1, 0);
mpz_init_set_ui(u2, 0);
mpz_init_set_ui(v2, 1);

mpz_inits(r1, r2);

mpz_set(r1, a);
mpz_set(r2, b);

while(mpz_cmp_ui(r2, 0))
{
    gmp_printf("r2 : %Zd\n", r2);
    mpz_sub_ui(r2, r2, 1);

    mpz_t q;
    mpz_init(q);
}}

循环似乎没有执行

寻找问题的根源,我试图简化循环,但每当我添加“mpz_init(q);”行时都会遇到问题(循环不再执行)。我用 a 等于 mpz_t 33 和 b 等于 mpz_t 5 调用了我的函数 euclid。

【问题讨论】:

  • 什么是r2?它是如何初始化的?请尝试创建minimal reproducible example 向我们展示。
  • @Someprogrammerdude 抱歉,我将编辑我的消息。 r2 是一个 mpz_t 变量。我在循环之前用 mpz_init(r2) 初始化它的值,并用 mpz_set(r2,e) 设置它的值,其中 e 是我的函数的参数。
  • 如果循环似乎没有执行,那只能是因为r2 等于0(那么mpz_cmp_ui 将返回零,即“假”)跨度>
  • @Someprogrammerdude 我同意这一点,但是添加 mpz_init(q) 行的简单事实使得循环不再执行。没有那条线,循环执行得很好。所以我不明白这条线(“mpz_init(q)”)如何影响r2的值。
  • 不过,minimal reproducible example 是有序的,包括您添加影响结果的 init 行的位置和方式。

标签: c++ c loops gmp


【解决方案1】:

像这样的问题(“我添加了一个看似无关的变量/函数调用并且行为发生了神秘的变化”)几乎总是未定义行为的结果。在这种情况下,UB在行

mpz_inits(r1, r2);

应该是的

mpz_inits(r1, r2, NULL);

(参见docs)。给mpz_inits 的列表必须以NULL 结尾,以便函数知道何时停止;否则会覆盖随机内存。

Valgrind 是发现此类问题的宝贵工具。

【讨论】:

    猜你喜欢
    • 2011-06-19
    • 2013-08-30
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多