Skip to content

Math.Min(double/float) do not handle NaN correctly #1396

Closed
@CoryCharlton

Description

@CoryCharlton

Library/API/IoT binding

System.Math

Visual Studio version

No response

.NET nanoFramework extension version

No response

Target name(s)

No response

Firmware version

No response

Device capabilities

No response

Description

According to IEEE 754:2019 (based on comments in the .NET Core implementation) NaN should be returned if either val1 or val2 are NaN.

There is also an opportunity here to optimize the Max and Min performance by removing one of the IsNan checks as demonstrated in the .NET Core implementation.

I'll look into implementing this change.

How to reproduce

Run these tests:

    [TestClass]
    public class System_Math_Tests
    {
        [TestMethod]
        public void Max_Double_returns_NaN_if_val1_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Max(double.NaN, Math.PI)));
        }

        [TestMethod]
        public void Max_Double_returns_NaN_if_val2_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Max(Math.PI, double.NaN)));
        }

        [TestMethod]
        public void Max_Float_returns_NaN_if_val1_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Max(float.NaN, (float) Math.PI)));
        }

        [TestMethod]
        public void Max_Float_returns_NaN_if_val2_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Max((float) Math.PI, float.NaN)));
        }

        [TestMethod]
        public void Min_Double_returns_NaN_if_val1_is_NaN()
        {
            // This test incorrectly returns PI
            Assert.IsTrue(double.IsNaN(System.Math.Min(double.NaN, Math.PI)));
        }

        [TestMethod]
        public void Min_Double_returns_NaN_if_val2_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Min(Math.PI, double.NaN)));
        }

        [TestMethod]
        public void Min_Float_returns_NaN_if_val1_is_NaN()
        {
            // This test incorrectly returns PI
            Assert.IsTrue(double.IsNaN(System.Math.Min(float.NaN, (float) Math.PI)));
        }

        [TestMethod]
        public void Min_Float_returns_NaN_if_val2_is_NaN()
        {
            Assert.IsTrue(double.IsNaN(System.Math.Min((float) Math.PI, float.NaN)));
        }
    }

Expected behaviour

NaN is returned when val1, val2, or both val1 and val2 are NaN.

Screenshots

No response

Sample project or code

No response

Aditional information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions