二次代数建议数组等返回功能

Quadratic Algebra advice for Array like return function

本文关键字:数组 返回 功能 二次      更新时间:2023-10-16

我有问题。我想编写一种方法,该方法使用pq-formula在二次代数上计算零。

我看到的C 不支持数组,与我正常使用的C#不同。如何获得零,1或2个结果?还有其他没有数组的方法吗?

实际上我不喜欢指针,因此我的实际代码被损坏了。

我很高兴有人能帮助我。

float* calculateZeros(float p, float q)
{
    float *x1, *x2;
    if (((p) / 2)*((p) / 2) - (q) < 0)
        throw std::exception("No Zeros!");
    x1  *= -((p) / 2) + sqrt(static_cast<double>(((p) / 2)*((p) / 2) - (q)));
    x2  *= -((p) / 2) - sqrt(static_cast<double>(((p) / 2)*((p) / 2) - (q)));
    float returnValue[1];
    returnValue[0] = x1;
    returnValue[1] = x2;
    return x1 != x2 ? returnValue[0] : x1;
}

实际上,此代码无法编译,但这是我到目前为止完成的代码。

有很大的问题;首先,我将放弃所有这些完全不必要的括号,它们只是使代码(非常困难(阅读:

float* calculateZeros(float p, float q)
{
    float *x1, *x2; // pointers are never initialized!!!
    if ((p / 2)*(p / 2) - q < 0)
        throw std::exception("No Zeros!"); // zeros? q just needs to be large enough!
    x1  *= -(p / 2) + sqrt(static_cast<double>((p / 2)*(p / 2) - q);
    x2  *= -(p / 2) - sqrt(static_cast<double>((p / 2)*(p / 2) - q);
    //  ^ this would multiply the pointer values! but these are not initialized -> UB!!!
    float returnValue[1];
    returnValue[0] = x1; // you are assigning pointer to value here
    returnValue[1] = x2;
    return x1 != x2 ? returnValue[0] : x1;
    //                    ^ value!      ^ pointer!
    // apart from, if you returned a pointer to returnValue array, then you would
    // return a pointer to data with scope local to the function – i. e. the array
    // is destroyed upon leaving the function, thus the pointer returned will get
    // INVALID as soon as the function is exited; using it would again result in UB!
}

,您的代码甚至都不会编译...

我看到的C 不支持数组

好吧...我假设您的意思是:'数组作为返回值或函数参数'。对于原始数组而言,这些只能作为指针传递。但是您可以接受结构和类作为参数,或将其用作返回值。您想返回两个计算值吗?因此您可以使用E。G。std::array<float, 2>;std::array是围绕原始数组的包装器,避免了您对后者的所有麻烦...由于正好有两个值,您也可以使用std::pair<float, float>std::tuple<float, float>

是否希望能够返回2、1或0值?std::vector<float>可能是您的选择...

std::vector<float> calculateZeros(float p, float q)
{
    std::vector<float> results;
    // don't repeat the code all the time...    
    double h = static_cast<double>(p) / 2; // "half"
    s = h * h;                             // "square" (of half)
    if(/* s greater than or equal q */)
    {
        // only enter, if we CAN have a result otherwise, the vector remains empty
        // this is far better behaviour than the exception
        double r = sqrt(s - q); // "root"
        h = -h;
        if(/* r equals 0*/)
        {
            results.push_back(h);
        }
        else
        {
            results.reserve(2); // prevents re-allocations;
                                // admitted, for just two values, we could live with...
            results.push_back(h + r);
            results.push_back(h - r);
        }
    }
    return results;
}

现在还有最后一个问题:由于甚至双重的精度也有限,因此可能会发生舍入错误(如果使用float,这是值得的;我建议我建议制作 all floats tobles tobles tobles并返回值!(。您永远不要比较确切的平等(someValue == 0.0(,但请考虑一些Epsilon涵盖不良圆的值:

-epsilon < someValue && someValue < +epsilon

好的,在给定的情况下,有两个最初涉及的比较,我们可能想做尽可能少的epsilon-comparison。所以:

double d = r - s;
if(d > -epsilon)
{
    // considered 0 or greater than
    h = -h;
    if(d < +epsilon)
    {
        // considered 0 (and then no need to calculate the root at all...)
        results.push_back(h);
    }
    else
    {
        // considered greater 0
        double r = sqrt(d);
        results.push_back(h - r);
        results.push_back(h + r);
    }
}

epsilon的价值?好吧,要么根据两个值的较小(将一些小因素乘以(,要么使用fix的固定值,要么用足够小的值计算,并确保使其具有正值...您可能对更多信息感兴趣就此事。您不必关心不成为C - 使用IEEEE754表示双打的所有语言的问题都是相同的。