4倍精度計算のための型 dd が用意されている。 仮数部が IEEE binary64 (いわゆる C の double) の 53 bits の2倍、 106 bits ということらしい。 なので、10進32桁くらい。
#include <kv/dd.hpp>
これでkv::ddという型が使える。 test/test-dd.cc では typedef kv::dd dd; としている。
使い方の確認のついでに、 GCC の __float128 との比較をしてみたい。 これは IEEE 754 の binary128 (4倍精度, ``Tetra Floating'') の実装であり、 仮数部が bits だそうだ。 となるので、 10進34桁弱ということだね。
``普通のパソコンのC言語の double'' は IEEE binary64 で、 仮数部が 53 bits (ケチ表現なので) で、 であるから、10進16桁程度である。
kv::dd と比べると、__float128 の方が十進2桁弱高精度?
/* * compare-dd-float128.cc * g++-mp-5 -I/opt/local/include compare-dd-float128.cc -lquadmath */ #include <iostream> #include <kv/dd.hpp> // dd #include <quadmath.h> // __float128 typedef kv::dd dd; void testdd(void) { int n; dd t, s, news; s = t = 1; std::cout.precision(33); for (n = 1; n <= 100; n++) { t /= n; news = s + t; std::cout << news << std::endl; if (s == news) break; s = news; } std::cout << " 12345678901234567890123456789012" << std::endl; std::cout.precision(34); std::cout << s << std::endl; std::cout << "最後の桁(小数第32桁)は6のはずだけど、2になる。32桁精度。" << std::endl; } void testfloat128(void) { int n; char message[128]; __float128 t, s, news; s = t = 1; for (n = 1; n <= 100; n++) { t /= n; news = s + t; quadmath_snprintf(message, sizeof(message), "%.33Qf", news); std::cout << message << std::endl; if (s == news) break; s = news; } std::cout << " 123456789012345678901234567890123" << std::endl; quadmath_snprintf(message, sizeof(message), "%.34Qf", news); std::cout << message << std::endl; std::cout << "最後の桁(小数第33桁)は2のはずだけど、3になる。34桁精度。" << std::endl; } int main(void) { std::cout << "dd" << std::endl; testdd(); std::cout << "__float128" << std::endl; testfloat128(); std::cout << "Mathematica N[E,40] の結果は" << std::endl; std::cout << "2.718281828459045235360287471352662497757" << std::endl; return 0; } |
そのうち速さ比べしてみよう。
桂田 祐史