私は奇妙な行動に出くわします。このプログラムでは、浮動小数点値がゼロに等しいかどうかを確認してみます。
#include <cstdlib>
#include <cmath>
#include <iostream>
int main ()
{
float fa (0), fb (0);
double da (0), db (0);
long double la (0), lb (0);
cout << "Float: " << (FP_ZERO == fpclassify (fa - fb) ) << endl;
cout << "Double: " << (FP_ZERO == fpclassify (da - db) ) << endl;
cout << "Long double: " << (FP_ZERO == fpclassify (la - lb) ) << endl;
cout << "Float: " << (FP_ZERO == fpclassify (fa - 42) ) << endl;
cout << "Double: " << (FP_ZERO == fpclassify (da - 42) ) << endl;
cout << "Long double: " << (FP_ZERO == fpclassify (la - 42) ) << endl;
return EXIT_SUCCESS;
}
プログラムの結果は予測可能です。
$ ./llvlg
Float: 1
Double: 1
Long double: 1
Float: 0
Double: 0
Long double: 0
しかし、Valgrindを介してプログラムを起動すると、長いダブルゼロの結果は間違ったものになります。
$ valgrind ./llvlg
==7521== Memcheck, a memory error detector
==7521== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7521== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==7521== Command: ./llvlg
==7521==
Float: 1
Double: 1
Long double: 0
Float: 0
Double: 0
Long double: 0
==7521==
==7521== HEAP SUMMARY:
==7521== in use at exit: 0 bytes in 0 blocks
==7521== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==7521==
==7521== All heap blocks were freed -- no leaks are possible
==7521==
==7521== For counts of detected and suppressed errors, rerun with: -v
==7521== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
それはバグですか、それとも予想される動作ですか?
UPD:ここで
入手可能なプログラムのソースコード。ビルドオプション:。私の環境:g++ main.cpp -O0 -o llvlg
$ uname -a Linux tiptop 4.8.0-53-generic #56-Ubuntu SMP Tue May 16 00:23:44 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
$ valgrind --version valgrind-3.12.0.SVN
$ cat /proc/cpuinfo ... model name : Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz ...
これは、Valgrindで予想される動作です。これは既知の制限です。内部的に長いdoubleは、64ビット(double)の精度でのみ表されます。
こちらをご覧ください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加