Boost.Multiprecisionの多倍長浮動小数点数型は、線形代数ライブラリであるBoost.uBLASでも使用できますが、式テンプレートがONだと、結果がおかしくなることがあるようです。以下、ベクトルでの簡単な「目的値に向かう処理」です。式テンプレートがオフの方から見てみます。
#include <iostream> #include <boost/multiprecision/cpp_dec_float.hpp> #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp> namespace mp = boost::multiprecision; namespace ublas = boost::numeric::ublas; using float_type = mp::number<mp::cpp_dec_float<50>, mp::et_off>; using vec = ublas::vector<float_type>; vec make_vector3(float_type x, float_type y, float_type z) { vec v(3); v[0] = x; v[1] = y; v[2] = z; return v; } vec normalize(vec v) { return v / ublas::norm_2(v); } int main() { vec p = make_vector3(0.0f, 0.0f, 0.0f); // 現在位置 vec q = make_vector3(3.0f, 0.0f, 6.0f); // 目的位置 vec v = normalize(q - p); // ベクトルを求める std::cout << "vector : " << v << std::endl; // 少しずつ目的位置に向かう float_type speed = 0.1f; // 速度 float_type accel = 0.1f; // 加速度 for (int i = 0; i < 20; ++i) { p += v * speed; speed += accel; } std::cout << "result pos : " << p << std::endl; }
vector : [3](0.447214,0,0.894427) result pos : [3](9.39149,0,18.783)
式テンプレートがオフだと正常な結果が返ってきています。しかし、式テンプレートがオンだと、以下のような結果になります:
vector : [3](1,0,1) result pos : [3](1,0,1)
全然違いますね・・・。
また、StackOverflowでの質問「Boost matrix product for multiprecision numbers」のように、式テンプレートがオンだと、まだいくつかの場面でうまくコンパイルが通らないケースがあるようです。これも式テンプレートをオフにしたら通りました。
#include <boost/multiprecision/cpp_dec_float.hpp> #include <boost/numeric/ublas/matrix.hpp> using namespace boost::multiprecision; using namespace boost::numeric::ublas; int main(int, char**) { matrix<number<cpp_dec_float<50>, et_off > > m (3, 3); matrix<number<cpp_dec_float<50>, et_off > > E (3, 3); E=prod(E,m); // OK : et_offにしたら通った return 0; }
式テンプレートを使うライブラリ同士を組み合わせてるところで、何らかの不整合が起きてる気がします。Boostのバージョンは1.53.0です。
この問題は、バグレポしておきました。
#8292 et_on with uBLAS become bad result