Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid using temporary variable with std::modf?

I've recently run into an issue where I got a segfault in MSVC where I wouldn't in GCC.

After hours I realized that apparently my version of MSVC does not support the following syntax:

double value = 3.4;
double fractional = std::modf(value, nullptr);

where I don't want/care about the whole part of the number.

Yes, I know I could do "3.4 - 3.0" or the like, but I'm concerned about specifically using modf in this way. Currently I can only see doing this via:

double temp; 
double value = 3.4;
double fractional = std::modf(value, &temp);

Is there a way around this temporary variable?

like image 222
Krupip Avatar asked May 20 '19 14:05

Krupip


2 Answers

If you do not need value afterwards you could call it as

double value = 3.4;
double fractional = std::modf(value, &value);

If you then still need the original value, you could reconstruct it easily.

PS: I did not find any mention of nullptr being a valid parameter. Maybe MSVC is right in going havoc.

PS2: I would not worry too much about the unecessary temporary. I would expect the compiler to generate similar code and explicitly mentioning the temporary is much cleaner and more readable as compared to passing value merely to avoid the temporary.

like image 113
463035818_is_not_a_number Avatar answered Sep 30 '22 16:09

463035818_is_not_a_number


You could write a simple wrapper to do this:

double frac(double value)
{
    double temp;
    return std::modf(value, &temp);
}

This way the compiler can possibly optimize temp away.

EDIT: This can also be combined with @formerlyknownas_463035818's idea without losing value:

double frac(double value)
{
    return std::modf(value, &value);
}

Or even better, @NathanOliver's comment (EDIT thanks to @Evg's comments):

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));
}

This one's best because it's clear and doesn't involve any tricks.

like image 37
Paul Evans Avatar answered Sep 30 '22 14:09

Paul Evans