使用 boost multiprecision/mpfr float - string could not be interpreted as valid integer 错误

working with boost multiprecision/mpfr float - string could not be interpreted as valid integer error

我编写了一个程序,可以对非常大的数字执行一些简单的算术运算。我成功地使用了 boost 多精度库中的 mpz_int 和 mpf_float,但发现我需要更高的精度才能实现我的目的。我一直在尝试使用 mpfr 库来更精确地定义浮点数。我能够编译我的代码,但现在收到运行时错误 libc++abi.dylib:终止,类型为 boost::exception_detail::clone_impl >:字符串“1572…[4000 位]…00.328”无法被捕获解释为有效整数。

我感觉是我试图将我创建的 mpfr_float 转换为导致问题的整数。我从一个整数字符串初始化浮点数,并在尝试向下舍入并转换为整数之前进行一些除法。这是我的类型定义:

typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<4680> > bloatfloat;

我的声明:

bloatfloat seed(“4716…etc.”);

和我尝试的转换:

boost::multiprecision::mpz_int seedint = seed.convert_to<boost::multiprecision::mpz_int>();

如果有人能帮我完成这个转换并避免运行时错误,我将不胜感激。我认为我的困惑的根源可能比这更深,所以我想解释一下我的项目,看看是否有人能告诉我我正在做的事情是否有更根本的错误。

我正在尝试创建看似随机但由可预测的伪随机函数构建的文本页面。因此,如果有人输入 1、2、3,他们会注意到三页文本之间没有模式,但每次输入这些数字中的任何一个都会得到相同的文本。我正在尝试创建 29 个字符的页面的所有可能性 3200 次,或 29^3200 种可能性(大约 10^4680)。

我正在使用哈顿序列生成伪随机质量,并将结果乘以 29^3200。

这是我的哈顿序列:

while (input>0) {
    denominator *=3;
    numerator = numerator * 3 + (input%3);
    input = input/3;
}

然后我将结果数字进行基数转换为基数 29 以获得一页文本。最初我使用 mpz_int 表示 29^3200(从字符串初始化)——但我发现这会产生重复模式。取决于 halton 序列的分母是什么。例如,产生分母 243 的输入将产生一页文本,其中包含 3200 个字符重复的相同 162 个字符,只是位置不同。

这是我程序的基本转换段:

boost::multiprecision::mpz_int seedint(seed); //converts from mpf_float
boost::multiprecision::mpz_int holder = 0;
std::string permuda [29] = {" ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", ",", "."};
std::string book = "";
holder = seedint%29;
int conversion = holder.convert_to<int>();
book = permuda[conversion];
while (seedint>=29) {
    seedint = seedint/29;
    holder = seedint%29;
    conversion = holder.convert_to<int>();
    book.insert(0,permuda[conversion]);
}
std::cout << book << "\n";

我数学不太好,无法理解为什么会出现这种重复,但凭直觉我改成了浮点数。我发现这样做效果更好——模式更短并且只会开始出现在输出字符串的开头(代表较高的值),但最终它们仍然存在并且可以识别。我发现 mpf_float 比 mpf_float_1000 效果更好,而且在产生更多看似随机的结果方面,它们都比 mpz_int 好得多。

正如我之前提到的,我的表面问题很简单:如何避免此运行时错误?但我更深层次的担忧是:a)为什么会出现这些模式?我是否正确认为更精确的浮点数会消除这些重复的字符串? b) 如果是这样,mpfr_float 是最好的数据类型吗?我应该给它什么程度的精度? c) 如果不是,我应该使用什么数据类型?

我非常感谢任何能回答这些问题的人。

---编辑---

我只是坚持使用 mpf_float,使用 29^3280 作为种子,并删除最后 80 个重复的字符,从而解决了我遇到的问题。不过,我仍然对固定精度和可变精度感到好奇。当我尝试使用更高的模板参数定义固定精度 gmp_float 时,我得到了更糟糕的结果。什么是固定精度和可变精度,为什么会产生这样的结果?

如果要四舍五入,请指定四舍五入:

seed = floor(seed); // round down

Live On Coliru

#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/mpfr.hpp>
#include <iostream>

namespace bmp = boost::multiprecision;

int main() {

    typedef bmp::number<bmp::mpfr_float_backend<4680> > bloatfloat;

    bloatfloat seed(
            "721201701982919384816919444629094602157676451009178493145697699033198799100795129"
            "461065252402772377100211702907679573288486469509354650292261514983089857585626889"
            "148299172516026989131041249763387900393649171847047199176208319323777423754787299"
            "899902453021655169650961976509782411649465051858878446823598416509136950922118426"
            "589618889559294511223766379025710403342501323543498101455439622897437844155269586"
            "993049821123424147085390549823755712672917476850165059107549100936676307424188564"
            "036471526370341311363147513165267081098820842568364867108467458147148215066631620"
            "521442723811840296249653692907217273194142954467472723479281126853419846351214589"
            "919458685154151951719281841322812833916704023062806547205146388218774938812715995"
            "71277364984644114752231471655539342153193201013.261");

    seed = floor(seed); // round down
    auto seedint = seed.convert_to<bmp::mpz_int>();

    std::cout << seedint;
}

版画

72120170198291938481691944462909460215767645100917849314569769903319879910079512946106525240277237710021170290767957328848646950935465029226151498308985758562688914829917251602698913104124976338790039364917184704719917620831932377742375478729989990245302165516965096197650978241164946505185887844682359841650913695092211842658961888955929451122376637902571040334250132354349810145543962289743784415526958699304982112342414708539054982375571267291747685016505910754910093667630742418856403647152637034131136314751316526708109882084256836486710846745814714821506663162052144272381184029624965369290721727319414295446747272347928112685341984635121458991945868515415195171928184132281283391670402306280654720514638821877493881271599571277364984644114752231471655539342153193201013