如何避免在 std::modf 中使用临时变量?

whn*_*whn 5 c++ modulo fractions cmath visual-c++

我最近遇到了一个问题,我在 MSVC 中遇到了段错误,而在 GCC 中却没有。

几个小时后,我意识到显然我的 MSVC 版本不支持以下语法:

double value = 3.4;
double fractional = std::modf(value, nullptr);
Run Code Online (Sandbox Code Playgroud)

我不想要/关心数字的整个部分。

是的,我知道我可以做“3.4 - 3.0”之类的,但我担心以这种方式专门使用 modf。目前我只能通过以下方式看到这样做:

double temp; 
double value = 3.4;
double fractional = std::modf(value, &temp);
Run Code Online (Sandbox Code Playgroud)

有没有办法绕过这个临时变量?

Pau*_*ans 5

您可以编写一个简单的包装器来执行此操作:

double frac(double value)
{
    double temp;
    return std::modf(value, &temp);
}
Run Code Online (Sandbox Code Playgroud)

这样编译器就可以优化temp掉。

编辑:这也可以与@previousknownas_463035818 的想法结合而不会丢失value

double frac(double value)
{
    return std::modf(value, &value);
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,@NathanOliver 的评论(编辑感谢 @Evg 的评论):

double frac(double value)
{
    int sign = value >= 0 ? 1 : -1;
    double avalue = std::abs(value)
    return std::isinf(value) ? 0.0 : sign * (avalue - std::floor(avalue));
}
Run Code Online (Sandbox Code Playgroud)

这个最好,因为它很清楚,不涉及任何技巧。

  • 请注意,第二个 `frac` 为负输入返回不正确的结果:`frac(-3.14) = 0.86`,但它应该是 `-0.14`。 (2认同)

for*_*818 5

如果您value之后不需要,您可以将其称为

double value = 3.4;
double fractional = std::modf(value, &value);
Run Code Online (Sandbox Code Playgroud)

如果您仍然需要原始值,则可以轻松重建它。

PS:我没有发现任何提及nullptr作为有效参数的内容。也许 MSVC 是正确的。

PS2:我不会太担心不必要的临时。我希望编译器生成类似的代码,与value仅仅为了避免临时而传递相比,明确提及临时更清晰、更易读。

  • `std::modf(value, &value)` 总是让我紧张。我必须检查以确保第一个参数没有被引用,否则可能会出现问题。在这种情况下,这很好,但它只会触发我的偏执狂。 (5认同)