Skip to content

Feature request: isnan() function #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sylque opened this issue May 21, 2025 · 7 comments
Closed

Feature request: isnan() function #22

sylque opened this issue May 21, 2025 · 7 comments

Comments

@sylque
Copy link

sylque commented May 21, 2025

I'm witnessing the following behavior when evaluating an expression:

  • nan == nan returns 0.0
  • nan != nan returns 1.0
@Blake-Madden
Copy link
Owner

Yeah, both of these scenarios should return NaN, unless you disagree. Thoughts?

@sylque
Copy link
Author

sylque commented May 21, 2025

I initially expected nan == nan to return 1.0 and nan != nan to return 0.0.

Then I tried x == nan with x defined as const double x = std::numeric_limits<float>::quiet_NaN() and, to my surprise, it returned 0.0 as well!

So I checked the IEEE standard and found this:


Any comparison with NaN (except !=) will return false, including comparing NaN with itself.

Comparison Result
NaN == NaN false
NaN != NaN true
NaN < any false
NaN > any false
std::isnan(NaN) true

So the current behavior perfectly conforms to the standard!

But then, how do I compare a number to NaN in tinyexpr++? It seems the library lacks an equivalent to std::isnan().

Oddly enough, there is a NAN entry in tinyexpr++ function list. But the doc is somewhat broken (no argument, no parenthesis) and it doesn't seem to evaluate as it should in an expression.

@sylque sylque changed the title Incorrect NaN evaluation in boolean expressions Feature request: isnan() function May 21, 2025
@Blake-Madden
Copy link
Owner

NA (or NA()) just returns NaN. So you can do something like this:

IF(5 < 4, NA(), TRUE)

This will evaluate to NaN. It basically behaves like NA() in Excel.

@Blake-Madden
Copy link
Owner

Yes, I need to add an ISNAN() (and perhaps ISNA() also for parity with Excel).

@Blake-Madden
Copy link
Owner

Yeah, in C++ comparing NaN with NaN will produce the IEEE standard results...but I'm just not liking that at all.

In Excel, =NA() = NA() and =NA() < NA() will yield #N/A. And in SQL, doing any comparison with NULL results in NULL. Unless you are really opposed to it, I'm going to make the presence of NaN in any comparison operation result in NaN to work the way Excel works. That just seems so much more natural to me.

@sylque
Copy link
Author

sylque commented May 21, 2025

I'm not opposed to it, but frankly both ways sound unnatural to me.
If I were in your shoes, I'd probably stick to the IEEE floating-point standard, if only to answer "standard!" to anyone complaining :-)

@sylque
Copy link
Author

sylque commented May 22, 2025

For those landing here:

Until ISNAN() is supported natively, it can be added manually using a custom function:

#include "tinyexpr.h"
#include <iostream>

double isnan(double val) { 
    return std::isnan(val) ? 1.0 : 0.0; 
}

int main() {
    const double x = std::numeric_limits<float>::quiet_NaN();
    
    te_parser tep;
    tep.set_variables_and_functions({{"x", &x}, {"ISNAN", isnan}});
    
    const double result = tep.evaluate("ISNAN(x)");
    
    std::cout << "The expression " << tep.get_expression() << " evaluates to " << result << "\n";
}

Blake-Madden added a commit that referenced this issue May 24, 2025
Although this is different from the C++ standard, this is how spreadsheet formulas work and is (IMO) more intuitive.
#22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants