Целочисленный расчет биномиального коэффициента с использованием boost::math::binomial_coefficient, возвращающий значение как boost::multiprecision::cpp_int? Как?

Я хотел бы рассчитать биномиальный коэффициент как целое число примерно до numberLeaves=100, K=10. Я считаю, что это должно быть возможно сохранить примерно в 128-битном целом числе.

Поэтому я хотел бы использовать boost::multiprecision::cpp_int для хранения результата и использовать boost::math::binomial_coefficient<boost::multiprecision::cpp_int> для его вычисления:

// Invalid because the template argument must be a floating-point type!
boost::multiprecision::cpp_int number_branch_combinations = 
    boost::math::binomial_coefficient<boost::multiprecision::cpp_int>(numberLeaves, K);

К сожалению, хотя биномиальный коэффициент является целым числом, приведенный выше код недействителен, поскольку boost::math::binomial_coefficient требует, чтобы возвращаемое значение было типом с плавающей запятой, утверждая, что:

... аргумент шаблона должен быть вещественным типом, таким как float или double, а не целочисленным типом - это слишком легко переполнит!

Как уже отмечалось, в моем случае я ожидаю, что результат вычисления биномиального коэффициента будет соответствовать примерно 128 битам, и мне бы хотелось, чтобы он был целым числом.

Поэтому я решил передать boost::multiprecision::cpp_dec_float в качестве аргумента шаблона для boost::math::binomial_coefficient, а затем выполнить преобразование из возвращаемого значения с плавающей запятой (путем округления) в ближайшее целое число.

К сожалению, я не могу найти способ преобразовать boost::multiprecision::cpp_dec_float в boost::multiprecision::cpp_int. Похоже, что выполнение преобразования с потерями строго запрещено библиотекой boost::multiprecision:

cpp_int             cppi(2);
cpp_dec_float_50    df(cppi);    // OK, int to float
df                  = static_cast<cpp_dec_float_50>(cppr);  // OK, explicit rational to float conversion
// However narrowing and/or implicit conversions always fail:
cppi                =   df;    // Compiler error, conversion not allowed

Сейчас я просто пишу свою собственную функцию для вычисления биномиального коэффициента и возврата значения в виде целого числа.

Мне трудно поверить, что буквально невозможно использовать boost::math::binomial_coefficient для вычисления биномиального коэффициента и вернуть его как boost::multiprecision::cpp_int.

Можно ли использовать boost::math::binomial_coefficient для вычисления биномиального коэффициента и вернуть его как boost::multiprecision::cpp_int?


person Dan Nissenbaum    schedule 27.03.2014    source источник


Ответы (2)


Мне трудно поверить, что буквально невозможно использовать boost::math::binomial_coefficient для вычисления биномиального коэффициента и вернуть его как a boost::multiprecision::cpp_int.

Как вы думаете, почему в это так трудно поверить?

Это был очевидный выбор дизайна, который был задокументирован как таковой, и в то время это имело большой смысл.

Boost Multiprecision появился только в версии 1_53. Я думаю, что binomial_coefficient намного старше этого (хотя я не проверял).

Таким образом, вместо того, чтобы выражать свое отвращение, вам, вероятно, следует поговорить с разработчиками в списках рассылки Boost, чтобы предложить эту новую функцию. Сопровождающие библиотеки Boost обычно очень хотят интегрироваться с (новыми) библиотеками.

Как вы понимаете, сейчас вы можете обернуть функцию, выполнив преобразование. Это faaar от идеального, но это меньше работы, чем поставить патч для Boost Math самостоятельно :)

person sehe    schedule 27.03.2014
comment
Мммм? Этот комментарий был случайно репостнут? Интересный... :) - person sehe; 12.04.2014
comment
На самом деле, я просматривал вопрос и изменил формулировку! Незначительная деталь, но и времени на это ушло немного. Я забыл, что вы получите предупреждение, поэтому я буду избегать этого в будущем, если в этом нет необходимости. - person Dan Nissenbaum; 12.04.2014
comment
О, я тоже так иногда делаю. Хоть и редко с комментариями. Ваше здоровье :) - person sehe; 12.04.2014
comment
У меня есть этот вопрос, который я только что опубликовал, на случай, если вы захотите попробовать :) to-cpp-dec-float0" title="как преобразовать boostmultiprecisioncpp int в cpp dec float0"> stackoverflow.com/questions/23027285/ - person Dan Nissenbaum; 12.04.2014

Вот что я использую, чтобы получить общее количество n выберите k:

boost::multiprecision::cpp_int BinomialCoefficient(unsigned int n, unsigned int k) {
  if (k == 0) { return 1; }
  else { return (n * BinomialCoefficient(n - 1, k - 1)) / k; }
}

Это было адаптировано из этого ответа, и я должен сказать, что это помогло мне.

person Angus Dobson    schedule 08.10.2015
comment
Да - это то, что я тоже делаю. Хотел бы я, чтобы у меня было время внести свой вклад в Boost! - person Dan Nissenbaum; 09.10.2015