为什么Boost多precision与升压有理数库工作吗? [英] Why does Boost multiprecision not work with Boost rational number library?
问题描述
我使用升压1.55.0铿锵3.5.0和gcc 4.8.1。
I'm using Boost 1.55.0 with clang 3.5.0 and gcc 4.8.1.
现在我想计算阶乘多达256个(没有precisionloss):
Now I would like to compute factorials up to 256 (with no precisionloss):
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
int main(){
using boost::multiprecision::uint128_t;
using boost::rational;
using std::cout;
using std::endl;
typedef unsigned long long unsigned_int;
// typedef uint128_t unsigned_int;
rational<unsigned_int> r((unsigned_int)1,
//((unsigned_int)1)<<127);
~(((unsigned_int)-1)>>1));
unsigned_int n_I = 1;
cout << "0!:\t\t" << r << endl;
cout << "1!:\t\t" << r << endl;
for(unsigned_int i=2; i<257; ++i){
r *= i;
cout << i << "!:\t\t" << r << endl;
}
return 0;
}
边注:大阶乘在二进制重新presentation许多尾随零,所以我开始用1 /(2 ^ 127)的价值理性的变量。此自动保持分子尽可能小
Side note: Large factorials have many trailing zeros in the binary representation, so I start with a rational variable with the value of 1/(2^127). This automatically keeps the numerator as small as possible.
我的问题:
它不以 uint128_t
从boost多precision工作!
但它确实与工作无符号长长
!
My problem:
It does not work with uint128_t
from boost multiprecision!
but it does work with unsigned long long
!
下面是我的终端输出:
~/ccpp_projects/facultiy $ clang++ -I /usr/local/include/boost-1_55 faculty.cpp -o faculty
In file included from faculty.cpp:51:
In file included from /usr/local/include/boost-1_55/boost/multiprecision/cpp_int.hpp:12:
In file included from /usr/local/include/boost-1_55/boost/multiprecision/number.hpp:22:
In file included from /usr/local/include/boost-1_55/boost/multiprecision/detail/generic_interconvert.hpp:9:
In file included from /usr/local/include/boost-1_55/boost/multiprecision/detail/default_ops.hpp:2073:
/usr/local/include/boost-1_55/boost/multiprecision/detail/no_et_ops.hpp:25:4: error: implicit instantiation of undefined template
'boost::STATIC_ASSERTION_FAILURE<false>'
BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
^
/usr/local/include/boost-1_55/boost/static_assert.hpp:36:48: note: expanded from macro 'BOOST_STATIC_ASSERT_MSG'
# define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B )
^
/usr/local/include/boost-1_55/boost/static_assert.hpp:169:13: note: expanded from macro 'BOOST_STATIC_ASSERT'
sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\
^
/usr/local/include/boost-1_55/boost/rational.hpp:533:15: note: in instantiation of function template specialization
'boost::multiprecision::operator-<boost::multiprecision::backends::cpp_int_backend<128, 128, 0, 0, void> >' requested here
num = -num;
^
/usr/local/include/boost-1_55/boost/rational.hpp:139:61: note: in instantiation of member function
'boost::rational<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<128, 128, 0, 0, void>, 0> >::normalize' requested here
rational(param_type n, param_type d) : num(n), den(d) { normalize(); }
^
faculty.cpp:63:28: note: in instantiation of member function 'boost::rational<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<128, 128,
0, 0, void>, 0> >::rational' requested here
rational<unsigned_int> r((unsigned_int)1, ~(((unsigned_int)-1)>>1));
^
/usr/local/include/boost-1_55/boost/static_assert.hpp:87:26: note: template is declared here
template <bool x> struct STATIC_ASSERTION_FAILURE;
^
1 error generated.
附录
我刚刚编译我的code与G ++和它的作品在那里!
是否有某种方式来禁用BOOST静态断言为铛++?
I just compiled my code with g++ and it works there! Is there some way to disable BOOST STATIC ASSERT for clang++?
推荐答案
的实施正常化()
假设翻转号( I = -i
)的底层整数类型的是定义的操作。
The implementation of normalize()
assumed that flipping the sign (i = -i
) of the underlying integer type is a defined operation.
这是的情况下无符号长长
,但是的不的为 uint128_t
。
Yould
-
使用
cpp_rational
(看到它的的住在Coliru )
use
cpp_rational
(see it Live On Coliru)
手工分解出2的幂: 住在Coliru ,输出:
manually factor out the powers of 2: Live On Coliru, output:
0!: 1
1!: 1
2!: 1 x 2^1
3!: 3 x 2^1
4!: 3 x 2^3
...
255!: 62542083004847430224885350954338565259 x 2^247
256!: 62542083004847430224885350954338565259 x 2^255
这是有可能你首先想要的是什么?这将是更有效,也prevent溢满了128位。
This is likely what you wanted in the first place? It will be more efficient and also prevent overflowing the 128 bit.
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
int main(){
using boost::multiprecision::uint128_t;
uint128_t mantissa = 1;
unsigned int binary_exponent = 0;
std::cout << "0!:\t\t" << mantissa << std::endl;
std::cout << "1!:\t\t" << mantissa << std::endl;
for(unsigned i=2; i<257; ++i){
unsigned tmp = i;
while (tmp && ((tmp % 2) == 0))
{
binary_exponent += 1;
tmp /= 2;
}
mantissa *= tmp;
std::cout << i << "!:\t\t" << mantissa << " x 2^" << binary_exponent << std::endl;
}
}
这篇关于为什么Boost多precision与升压有理数库工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!