Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ NaN或false作为双精度返回值_C++_Nan_Logical Operators_Double Precision - Fatal编程技术网

C++ NaN或false作为双精度返回值

C++ NaN或false作为双精度返回值,c++,nan,logical-operators,double-precision,C++,Nan,Logical Operators,Double Precision,我有一个返回双精度值的函数。在某些情况下,结果为零,应该在调用方路由中相应地处理此结果。我想知道返回零(NaN、false等)代替双值数字的正确方法是什么: double foo(){ if (some_conditions) { return result_of_calculations; } else { // Which of the following is better? return std::numeric_limit

我有一个返回双精度值的函数。在某些情况下,结果为零,应该在调用方路由中相应地处理此结果。我想知道返回零(NaN、false等)代替双值数字的正确方法是什么:

double foo(){
    if (some_conditions) {
        return result_of_calculations;
    } else {
        // Which of the following is better?
        return std::numeric_limits<double>::quiet_NaN(); // (1)
        return 0;                                        // (2)
        return false;                                    // (3)
        return (int) 0;                                  // (4)
    }
}
if(bar==0)
与#3和#4一起使用是否安全?我可以将它与#2一起使用吗?或者我应该做类似于
fabs(bar-0)

一个人应该如何处理安静的情况?我在这个网站上读到(例如),比较NaN并不一定总是错误的。那怎么办


总之,如何返回假值来代替双精度值以供以后比较?

您不应将函数计算的实际值与进一步描述结果的附加消息(即错误状态)混合使用


好办法是:

  • 自定义结果结构

    struct foo_result_t
    {
        double value;
        bool state;
    };
    
    foo_result_t foo() {
        foo_result_t r;
        r.value = result_of_calculations;
        r.state = some_conditions;
        return r;
    }
    
    如果您需要从函数中获得更多信息,这可能是最好的方法,并且易于扩展。比如指出它为什么失败

    对于简单的情况,您也可以考虑使用<代码> STD::配对< /C> > < /P> 您还可以使用

    boost::optional
    ()

  • <> > C++异常方式< /P>
    double foo() {
        if(some_conditions) {
            return result_of_calculations;
        }
        else {
            throw some_exception;
        }
    }
    
    这看起来很优雅,但有时您可能希望保持代码无异常

  • 老派C风格的方式:

    bool foo(double& result) {
        if(some_conditions) {
            result = result_of_calculations;
            return true;
        }
        else {
            return false;
        }
    }
    
    这可能是最直接的一个,并且没有开销(异常、附加结构)。但函数试图返回两个值时看起来有点奇怪,但其中一个实际上是参数


  • 您不应将函数计算的实际值与进一步描述结果的附加消息(即错误状态)混用


    好办法是:

  • 自定义结果结构

    struct foo_result_t
    {
        double value;
        bool state;
    };
    
    foo_result_t foo() {
        foo_result_t r;
        r.value = result_of_calculations;
        r.state = some_conditions;
        return r;
    }
    
    如果您需要从函数中获得更多信息,这可能是最好的方法,并且易于扩展。比如指出它为什么失败

    对于简单的情况,您也可以考虑使用<代码> STD::配对< /C> > < /P> 您还可以使用

    boost::optional
    ()

  • <> > C++异常方式< /P>
    double foo() {
        if(some_conditions) {
            return result_of_calculations;
        }
        else {
            throw some_exception;
        }
    }
    
    这看起来很优雅,但有时您可能希望保持代码无异常

  • 老派C风格的方式:

    bool foo(double& result) {
        if(some_conditions) {
            result = result_of_calculations;
            return true;
        }
        else {
            return false;
        }
    }
    
    这可能是最直接的一个,并且没有开销(异常、附加结构)。但函数试图返回两个值时看起来有点奇怪,但其中一个实际上是参数


  • 没有足够的背景来完全回答这个问题。当
    某些条件的计算结果为false时,听起来您希望返回一个哨兵。但什么是正确的哨兵?回答这一问题主要取决于在何处以及如何使用
    foo()

    在大多数情况下,正确的答案都不是上述问题。也许抛出异常会更好。也许将界面更改为
    boolfoo(double&)
    boolfoo(double*)
    会更好。也许,正如Plasmah所建议的,将其更改为
    boost::optional foo()
    会更好

    如果sentinel更好,则正确的sentinel将取决于该值。假设调用方正在进行加法或乘法运算。如果不影响结果,则sentinel应分别为0.0或1.0。如果它应该完全放弃结果,那么NaN或Inf可能更有意义


    至于EPSILON问题,这取决于您希望如何处理另一个案例返回的接近零值。返回一个literal
    0.0
    值将产生一个与
    0.0
    精确比较的双精度值;但是,“应该”导致
    0.0
    的计算可能不会精确地导致
    0.0

    没有足够的上下文来完全回答这个问题。当
    某些条件的计算结果为false时,听起来您希望返回一个哨兵。但什么是正确的哨兵?回答这一问题主要取决于在何处以及如何使用
    foo()

    在大多数情况下,正确的答案都不是上述问题。也许抛出异常会更好。也许将界面更改为
    boolfoo(double&)
    boolfoo(double*)
    会更好。也许,正如Plasmah所建议的,将其更改为
    boost::optional foo()
    会更好

    如果sentinel更好,则正确的sentinel将取决于该值。假设调用方正在进行加法或乘法运算。如果不影响结果,则sentinel应分别为0.0或1.0。如果它应该完全放弃结果,那么NaN或Inf可能更有意义

    至于EPSILON问题,这取决于您希望如何处理另一个案例返回的接近零值。返回一个literal
    0.0
    值将产生一个与
    0.0
    精确比较的双精度值;但是,“应该”导致
    0.0
    的计算可能不会精确地导致
    0.0

    if(bar==0)与#3和#4一起使用安全吗

    #3
    #4
    编译与
    #2
    相同

    我可以和#2一起使用它吗?或者我应该做一些像fabs(bar-0) 是(您可以与
    #2
    一起使用):
    双栏=0=>
    bar==0

    然而!如果
    some_conditions==true
    branch可以通过一些计算返回(接近)零,并且您需要以相同的方式处理这种情况,那么在比较浮点值的相等性时,您需要使用通常的技巧

    另一方面,如果
    some_conditions==true
    分支可能返回零,但这种情况的处理方式应该与
    false
    分支的结果不同,那么您需要使用另一种方法。丹维尔列出了有用的替代方案

    对于比较
    NaN
    ,请使用

    if(bar==0)与#3和#4一起使用安全吗

    #3
    #4
    编译与
    #2相同auto hopefully( bool const cond ) -> bool { return cond; }
    auto fail( string const& s ) -> bool { throw runtime_error( s ); }
    
    auto foo()
        -> double
    {
        double const result = calculations();
        hopefully( calculations_succeeded() )
            || fail( "foo: calculations failed" );
        return result;
    }