Я написал программу, которая выполняет простые арифметические действия с очень большими числами. Мне удалось использовать mpz_int и mpf_float из библиотек повышения точности, но я обнаружил, что мне нужно больше точности для достижения моей цели. Я пытался использовать библиотеку mpfr для определения поплавка с большей точностью. Я смог скомпилировать свой код, но теперь получаю ошибку времени выполнения libc++abi.dylib: завершение с необработанным исключением типа boost::exception_detail::clone_impl >: Строка «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_float работает лучше, чем mpf_float_1000, и оба они намного лучше, чем mpz_int, с точки зрения получения более случайных результатов.
Как я упоминал ранее, мой поверхностный вопрос прост: как мне избежать этой ошибки во время выполнения? Но меня более глубоко беспокоит: а) почему появляются эти паттерны? Я прав, что поплавки с большей точностью устранят эти повторяющиеся строки? и б) если да, то является ли mpfr_float лучшим типом данных? какую степень точности я должен дать ему? c) если нет, то какой тип данных я должен использовать?
Я очень благодарен всем, кто может ответить на любой из этих вопросов.
---РЕДАКТИРОВАТЬ---
Я решил проблему, которая у меня была, просто придерживаясь mpf_float, используя 29 ^ 3280 в качестве семени и отрезая последние 80 символов, которые были повторяющимися. Однако мне все еще интересно узнать о фиксированной и переменной точности. Когда я попытался определить фиксированную точность gmp_float с более высоким параметром шаблона, я получил гораздо худшие результаты. Что такое фиксированная и переменная точность и почему она дает такие результаты?