次のようなものを使用できます。
#include <iostream>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
template <typename F> F sum (const F a, const F b, F &error) {
int round = fegetround();
fesetround(FE_TONEAREST);
F c = a + b;
fesetround(FE_DOWNWARD);
F c_lo = a + b;
fesetround(FE_UPWARD);
F c_hi = a + b;
fesetround(FE_TONEAREST);
error = std::max((c - c_lo), (c_hi - c));
fesetround(round);
return c;
}
int main() {
float a = 23.23528;
float b = 4.234;
float e;
std::cout << sum(a, b, e) << std::endl;
std::cout << e << std::endl;
}
最大エラー量の簡単な見積もりがerror
引数に返されます。丸めモードを切り替えると、浮動小数点ユニット(FPU)パイプラインがフラッシュされるため、非常に高速な速度を期待しないでください。
より良い解決策は、区間演算(変数の相関が考慮されていないため、悲観的な誤差間隔を与える傾向がある)、またはアフィン演算(変数の相関を追跡し、したがって、いくらか厳しい誤差範囲を与える)を試すことです。
これらの方法の入門書については、こちらをお読みください:
http ://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.8089