2026/11/07(土)kv-0.4.63
今回は計算結果の異常の可能性のある、比較的重大なbug-fixが2点です。
1つ目は、dd同士の除算の方向付き丸めのコードの書き方に問題があり、最適化オプションが-O1以上のときにinterval<dd>の除算が正しく計算されない可能性がある問題です。修正後は問題ありません。例えば、
#include <kv/interval.hpp>
#include <kv/dd.hpp>
#include <kv/rdd.hpp>
int main()
{
std::cout.precision(34);
kv::interval<kv::dd> x, y, z, w;
x = 1;
y = 3;
z = x / y;
std::cout << z << "\n";
w = 1 / z;
std::cout << w << "\n";
}
みたいなコードを実行すると、最適化オプションなしまたは-O0では、[0.3333333333333333333333333333333323,0.3333333333333333333333333333333354] [2.999999999999999999999999999999963,3.000000000000000000000000000000019]のように3を含む区間になるところ、-O1以上では、
[0.3333333333333333333333333333333323,0.3333333333333333333333333333333354] [3,3]のように幅0の区間になってしまっています。
原因は、kv/rdd-hwround.hpp の中のdiv_up, div_down関数の中で、丸めモードを変更している箇所はvolatile変数に代入して最適化を抑制しているのですが、
v1 = z1; v2 = (((v3 + v5) + (-v1) * v8) + v6) + v4;のような箇所があって、ここが問題でした。
v1 = -z1; v2 = (((v3 + v5) + v1 * v8) + v6) + v4;のように書き直して、問題を解消しました。(-v1)*v8が、-(v1*v8)にされてしまうことがあり、これで丸めの向きが壊れます。なんかもう、人類の注意力の限界を感じました。
2つ目は、ベキ級数演算(psa.hpp)で、asin, acos, atan, asinh, acosh, atanhの計算が間違っていたというものです。2015/11/3にまとめて追加した関数で、全部に同じバグがありました。八木祥ノ介さん@筑波大学さん、ありがとうございます。ODEの右辺でこんな関数を使うことがなく、ずっと見逃されていました。
やはり使われればこそ、こういうバグが見つかります。ありがたいことです。そして、最近はAIのアシストにより、Linuxカーネルを始めとしたさまざまな基盤ソフトウェアがすごい勢いでbug-fixされるようになりました。kvも完成度を高めていかねばなりません。