Skip to content

Instantly share code, notes, and snippets.

@mskashi
Last active March 1, 2016 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mskashi/b7e5a5796a3fa1779fa1 to your computer and use it in GitHub Desktop.
Save mskashi/b7e5a5796a3fa1779fa1 to your computer and use it in GitHub Desktop.
Visual C++でのfesetroundの動作チェック
#include <iostream>
#include <cfenv>
#include <cmath>
int check_rounding()
{
volatile double x, y, z;
x = 1;
y = pow(2., -55);
z = x + y;
if (z > 1) return 2; // up
z = x - y;
if (z == 1) return 0; // nearest
z = - x + y;
if (z == -x) return 1; // down
return 3; // chop
}
int main()
{
std::cout << check_rounding() << "\n";
fesetround(FE_TONEAREST);
std::cout << check_rounding() << "\n";
fesetround(FE_DOWNWARD);
std::cout << check_rounding() << "\n";
fesetround(FE_UPWARD);
std::cout << check_rounding() << "\n";
fesetround(FE_TOWARDZERO);
std::cout << check_rounding() << "\n";
}
@mskashi
Copy link
Author

mskashi commented Feb 26, 2016

Visual C++ 2013で64bitでコンパイルして実行すると、本来
0
0
1
2
3
と表示されるべきなのが、
0
0
2
1
3
と表示されてしまう。つまり、upとdownの動作が入れ替わっている。32bitなら大丈夫。

@loliGothicK
Copy link

Study Group Draft – March 16, 2012
によると、IEEE754ではpowはサポートされてないようなので
丸め方向の指定は保証されないと思います

@mskashi
Copy link
Author

mskashi commented Mar 1, 2016

コメントありがとうございます。
powの誤差ではなく、その後のx+yやx-yの誤差を利用して現在の丸めモードを検出しようとしています。
powが影響を受ける可能性も否定できないので、2^(-55)はもう少し違う手段で生成した方がいいかもですね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment