Skip to content
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

Unexpected compMin behavior. #1215

Closed
MaxSac opened this issue Jan 11, 2024 · 3 comments · Fixed by #1240
Closed

Unexpected compMin behavior. #1215

MaxSac opened this issue Jan 11, 2024 · 3 comments · Fixed by #1240

Comments

@MaxSac
Copy link

MaxSac commented Jan 11, 2024

I tried to calculate the compMin from a vector which includes a NaN.
The result seems to be dependent on the position of the NaN in the vector.
It may be a different behavior than the c++ standard suggests [IEEE floating-point arithmetic (IEC 60559)] (and my naive intuition 😆 ).

#include <glm/glm.hpp>
#include <glm/gtx/component_wise.hpp>
#include <iostream>
#include <limits>

int main(int argc, char* argv[])
{
    // Option I.
    std::cout << glm::compMin(glm::vec2(std::numeric_limits<float>::quiet_NaN(), 1.f)) << std::endl;
    // >>> nan
    std::cout << glm::compMin(glm::vec2(1.f, std::numeric_limits<float>::quiet_NaN())) << std::endl;
    // >>> 1

     // Option II.
    std::cout << std::fmin(std::numeric_limits<float>::quiet_NaN(), 1.f) << std::endl;
    // >>> 1
    std::cout << std::fmin(1.f, std::numeric_limits<float>::quiet_NaN()) << std::endl;
    // >>> 1

    return 0;
}

Is this kind of functionality intentional?

@gottfriedleibniz
Copy link

gottfriedleibniz commented Jan 11, 2024

GLSL defines min as:

Returns y if y < x; otherwise it returns x

which should match std::min's behaviour (not std::fmin). Unfortunately, the inconsistency in special-value behaviour between IEEE-operators vs ternary-logic will emerge elsewhere too.

@christophe-lunarg
Copy link

Erm, the comment, the example don't match. Without clarification, I will just close this issue. Maybe that's a feature request for a fcompMin function. unclear.

@MaxSac
Copy link
Author

MaxSac commented Jan 12, 2024

Sorry for the incorrect minimal working example. I wrote it yesterday in a hurry and have now corrected it.

To give a little bit of background.
I tried to calculate the interaction distance from a ray to a box, as sketched in the picture.
sketch-1

I wrote the following code and was quite surprised that a) and b) gave different results.

#include <array>
#include <glm/glm.hpp>
#include <glm/gtx/component_wise.hpp>
#include <iostream>
#include <limits>

std::array<float, 2> intersection(glm::vec2 corner1, glm::vec2 corner2,
    glm::vec2 origin, glm::vec2 invDirection)
{
    auto tMin = (corner1 - origin) * invDirection;
    auto tMax = (corner2 - origin) * invDirection;

    auto tEnter = glm::min(tMin, tMax);
    auto tExit = glm::max(tMin, tMax);

    auto enterMax = glm::compMax(tEnter); 
    auto exitMin = glm::compMin(tExit);  

    return std::array<float, 2> { enterMax, exitMin };
}

int main(int argc, char* argv[])
{
    auto c1 = glm::vec2(1, 1);
    auto c2 = glm::vec2(2, 2);

    // a)
    auto origin1 = glm::vec2(1, 0);
    auto invDirection1 = glm::vec2(std::numeric_limits<float>::quiet_NaN(), 1.f);
    auto intersection_points1 = intersection(c1, c2, origin1, invDirection1);
    std::cout << "entry: " << intersection_points1[0] << ", exit: " << intersection_points1[1] << std::endl;
    // >>> entry: nan, exit: nan


    // b)
    auto origin2 = glm::vec2(0, 1);
    auto invDirection2 = glm::vec2(1.f, std::numeric_limits<float>::quiet_NaN());
    auto intersection_points2 = intersection(c1, c2, origin2, invDirection2);
    std::cout << "entry: " << intersection_points2[0] << ", exit: " << intersection_points2[1] << std::endl;
    // >>> entry: 1, exit: 2

    return 0;
}

Technically I can understand what happens, but it was against my naive expectation.
I guess using something like fcompMax would help in this case and would be a nice feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants