使用Valgrind的std :: fpclassify对于long double的错误结果

时间:2017-06-01 20:25:08

标签: c++ gcc valgrind

我遇到了奇怪的行为。在这个程序中,我尝试检查浮点值是否等于零:

#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
可用程序的源代码here 构建选项: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 ...

1 个答案:

答案 0 :(得分:1)

这是Valgrind的预期行为 - 一个已知的限制。内部long double仅以64位(双精度)表示。

请参阅here