使用boost multiprecision / mpfr float - string无法解释为有效的整数错误

时间:2015-04-09 16:38:41

标签: c++ boost base mpfr multiprecision

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

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

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)的页面的所有可能性。

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

这是我的哈顿序列:

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

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

以下是我的程序的基本转换段:

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)如果没有,我应该使用什么数据类型?

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

--- --- EDIT

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

1 个答案:

答案 0 :(得分:1)

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

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