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;
}
|
そのうち速さ比べしてみよう。
桂田 祐史