我写了一个程序,可以用非常大的数字执行一些简单的算术运算。我成功地使用了boost多精度库中的mpz_int和mpf_foat,但发现我需要更高的精度才能达到目的。我一直在尝试使用mpfr库来更精确地定义浮点值。我本来可以编译我的代码,但现在收到运行时错误libc++abi.dylib:以boost::exception_detail::clone_inpl>类型的未捕获异常终止:字符串"1572…[4000位]…00.328"无法解释为有效整数。
我有一种感觉,是我试图将我创建的mpfr_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)。
我使用哈尔顿序列来生成伪随机质量,并将结果乘以29^3200。
这是我的暂停序列:
while (input>0) {
denominator *=3;
numerator = numerator * 3 + (input%3);
input = input/3;
}
然后,我将得到的数字以29为基数进行基数转换,得到一页文本。最初,我使用mpz_int表示29^3200(从字符串初始化),但我发现这会产生重复的模式。这取决于哈尔顿序列的分母是多少。例如,产生分母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_foat比mpf_floot_1000工作得更好,而且在产生更随机的结果方面,它们都比mpz_int好得多。
正如我之前提到的,我的表面问题很简单:如何避免这个运行时错误?但我更深层次的担忧是:a)为什么会出现这些模式?更高精度的浮点运算可以消除这些重复的字符串,我说得对吗?b)如果是,mpfr_float是最佳数据类型吗?我应该给它多精确?c) 如果没有,我应该使用什么数据类型?
我非常感谢任何能够回答这些问题的人。
---编辑---
我只需坚持使用mpf_foat,使用29^3280作为种子,并剪掉最后80个重复的字符,就解决了我遇到的问题。不过,我仍然对固定精度和可变精度感到好奇。当我试图用更高的模板参数定义一个固定精度的gmp_float时,我得到了更糟糕的结果。什么是固定精度和可变精度,为什么会产生这样的结果?
如果要舍入,请指定舍入:
seed = floor(seed); // round down
在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