std::strod()
文字列を double に変換します。しかし、ある特定のケースでは、わずかな小数エラーがあります。このエラーは、 および にも表示されatof()
ますsscanf()
。このエラーは、次の条件がすべて満たされている場合にのみ発生します。
- Visual Studio 2015 (または VS 2015 update 1)
- 64 ビット (x64) 用にビルド
- を呼び出して
_controlfp_s()
「マイナス無限大への丸め」を設定します - 数値には小数部分があります (例: 0.5 または 2.5 (整数ではありません))。
(64 ビットの Windows 8.1 Enterprise でのみテストしました) 簡単な例を次に示します。
#include <string>
inline double fromString(const std::string& s) {
size_t idx;
return std::stod(s, &idx);
}
int main()
{
double res1 = fromString("0.5");
unsigned tmp;
_controlfp_s(&tmp, RC_DOWN, MCW_RC);
double res2 = fromString("0.5");
_controlfp_s(&tmp, RC_NEAR, MCW_RC);
double res3 = fromString("0.5");
}
std::stod()
std::calling strtod()
stdlib.h
を呼び出しています。res1
正確に 0.5 にres2
なりますが、0.50000000000000011 になります
_controlfp_s(&tmp, RC_DOWN, MCW_RC);
丸め誤差を制御します。この場合、負の無限大に向かって丸めるように設定されています。_controlfp_s(&tmp, RC_NEAR, MCW_RC);
デフォルトに戻すとstrod()
、再び正確になり、res3
0.5になります。
一部の 10 進数は正確に表現できないことに注意してください。ただし、2.5、0.5、0.375 などの一部の数値は使用できますが、上記の例ではすべて丸め誤差が発生します。
変ですね。
何か間違っているのでしょうか、それとも Visual Studio の標準ライブラリのバグですか?