【问题标题】:Convert uint64 to GMP/MPIR number将 uint64 转换为 GMP/MPIR 编号
【发布时间】:2020-08-19 00:16:25
【问题描述】:

我在 Windows (MSVC 2010) 上使用 MPIR 2.4.0,并尝试将无符号 64 位整数添加到 mpz_t 数字。但是似乎 MPIR/GMP 不支持 64 位整数和 mpz_t 之间的直接转换。这是否意味着我必须将我的 uint64 转换为字符串并通过 mpz_init_set_str 读取? 这既不是很吸引人,也不是很快 - 两次转换都是徒劳的。

我是否遗漏了什么或者在这里使用的技巧/黑客是什么?

干杯,

菲利普

【问题讨论】:

    标签: c++ gmp uint64


    【解决方案1】:

    Banthar 建议使用 mpz_import,但我建议以下不依赖于平台字节序的方法:

    mpz_import(b, 1, 1, sizeof(a), 0, 0, &a);
    

    【讨论】:

    • 谢谢,正如斯蒂芬佳能所说:我不知道这个功能,非常有用:) 但我仍然认为这种大小的库不考虑 int64 是奇怪的:/跨度>
    • 实际使用mpz_import似乎比设置lhigher 32bits,mul_2exp要偏移32bits,然后加上low 32bits,如果数字为负,则取反mp_size要慢
    【解决方案2】:

    使用mpz_import:

    void mpz_set_ull( mpz_t rop, unsigned long long op )
    {
       mpz_import(rop, 1, 1, sizeof(op), 0, 0, &op);
    }
    

    编辑:根据Frank's comment更新代码。

    【讨论】:

    • 啊,很好。不知道这个功能。
    • 它看起来更好,但你必须处理字节序。我不确定这段代码是否正确处理。
    【解决方案3】:

    是的,如果您在不使用 LP64 模型的平台 (Windows) 上,则无法将 64 位整数分配给 mpz_t。您可以单独分配 64 位整数的高半部分和低半部分,然后将它们加在一起,而不是遍历字符串。仍然不是很干净,但几乎可以肯定更快。

    编辑:请参阅 Banthar 的答案以获得更好的解决方法。

    【讨论】:

      【解决方案4】:

      在 MPIR 3 上运行一些测试后,由于某种原因,mpz_import 在 64 位值上似乎较慢,下面的方法更丑,但 IME 表现更好(hi 是更高的 32 位,lo 是 UInt64 的低 32 位)

       mpz_set_ui(dest, hi);
       mpz_mul_2exp(dest, dest, 32);
       mpz_add_ui(dest, lo);
      

      如果 hi 部分为空,当然可以使用快捷方式,值得进行测试。

      如果是负Int64(有符号),则获取Abs,做上述操作,然后对mp_size字段取反。

      【讨论】:

        【解决方案5】:

        MPIR 2.4 引入了对 intmax_t 和 uintmax_t 的支持。请参阅 mpz_set_ux()/sx() 和 mpz_get_ux()/sx()。这些函数在 GMP 中不存在,但记录在 MPIR 2.4.0 手册中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多