C++において多倍長整数,多倍長浮動小数点を扱うライブラリとしてGMPが有名だ.
Visual C++を使っているのなら,GMPと互換のあるMPIRが導入しやすくて良い.
以下,VC10 (Visual Studio 2010)環境での話.
このMPIRはどうもC++の複素数クラスstd::complexと相性が悪いようだ.
#include <complex> #include <iostream> #include <iomanip> #include <mpirxx.h> int main() { std::complex<mpf_class> a(1.0, 2.0); std::complex<mpf_class> b(0.0, 1.0); std::complex<mpf_class> c1 = a + b; std::complex<mpf_class> c2 = a - b; std::complex<mpf_class> c3 = a * b; // std::complex<mpf_class> c4 = a / b; // error std::cout << "a =" << a << std::endl << "b =" << b << std::endl << "c1 =" << c1 << std::endl << "c2 =" << c2 << std::endl << "c3 =" << c3 << std::endl; // std::cout << "c4 =" << c4 << std::endl; return 0; }
「operator/=」から呼び出される「_Div」内部でエラーが出る.
そこでテンプレートの特殊化をする.
#pragma once #include <mpirxx.h> #if defined(_MSC_VER) &amp;&amp; (_MSC_VER == 1500) /* VC9 (Visual Studio 2008) */ #pragma comment(lib, "C:\\lib\\MPIR\\vc9\\mpirxx.lib") #pragma comment(lib, "C:\\lib\\MPIR\\vc9\\mpir.lib") #else if defined(_MSC_VER) &amp;&amp; (_MSC_VER == 1600) /* VC10 (Visual Studio 2010) */ #pragma comment(lib, "C:\\lib\\MPIR\\vc10\\mpirxx.lib") #pragma comment(lib, "C:\\lib\\MPIR\\vc10\\mpir.lib") #endif #include<complex> namespace std { template<> complex<mpf_class>&amp; complex<mpf_class>::operator/=(const complex<mpf_class>&amp; _Right) { // divide by other complex //this->_Div(_Right); mpf_class _Rightreal = (mpf_class)_Right.real(); mpf_class _Rightimag = (mpf_class)_Right.imag(); mpf_class bunbo = _Rightreal * _Rightreal + _Rightimag * _Rightimag; mpf_class re = ( this->real() * _Rightreal + this->imag() * _Rightimag ) / bunbo; mpf_class im = ( this->imag() * _Rightreal - this->real() * _Rightimag ) / bunbo; this->real(re); this->imag(im); return (*this); } }
これでとりあえずは割り算もできるようになった.
計算精度については何も考えていない.
#突っ込みお待ちしてます.