Home > Net >  Why would someone write an if condition containing a float like this?
Why would someone write an if condition containing a float like this?

Time:01-26

I am looking through some code previously written by a senior developer in my company and I am curious about the reasoning behind the somewhat convoluted looking if statement they wrote (I would ask them directly if possible).

The code is intended to check if temperature readings from a sensor are valid. I believe negative readings were valid at the time, which explains the use of std::abs() and comparison of that to 0.000001 instead of just using temperature > 0, however I am unsure why they chose to subtract 0. as well. I have included a minimum working example, but the focus of my question is on why the statement includes the - 0. (just to convert float to a double? That seems to be what VSCode thinks it does) and if my assumption about needing to accept negative values while also needing to invalidate (very near) zero readings in the form of floats sounds correct.

#include <optional> 
#include <iostream>

void check_temp(std::optional<float> prev_temp, float cur_temp){

    if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
        (prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))
    {
        std::cout << "Temperature error detected!\n";
    }
    return;
}

int main(int argc, char const *argv[])
{
    std::optional<float> prev_temp = std::nullopt;
    float cur_temp = 0;

    while(1){
        std::cout << "Enter temp: ";
        std::cin >> cur_temp;
        check_temp(prev_temp, cur_temp);
        prev_temp = cur_temp;
    }

    return 0;
}

And to be very clear, the specific line (condition) I am looking for clarification on is:

(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)

CodePudding user response:

clarification on:

(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)

!prev_temp certainly tests if a previous temperature exist. Since it does not (in this clause), code continues "as if" previous temperature was zero. The subtraction with 0.0 instead of 0.0f is an oversight on the original programming. The same functionality and simpler code would have been std::abs(cur_temp - 0.0f) for illustrative purposes.

There is no reason for a double constant 1.0e-6 except for a pedantic compare against 1.0e-6 vs 1.0e-6f - which are different values. IOWs, 1.0e-6f < 1.0e-6 might be true, so the equivalent replacement is std::abs(cur_temp) <= 1e-6f - note the <=.

The compare against the double 100.0 again is weak programming. Nothing gain by using double. It might not emit different code had is been 100.f with a good optimizing compiler.

IMHO

  if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
    (prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))

better as

  if ((!prev_temp && std::abs(0.0f - cur_temp) < 1e-6f) ||
    (prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0f))

The only reason I see for masterfully coding in this fashion is to try to steer the compiler output. Such coding applies to the compiler of that vintage. Better now to code for clarity.

  • Related