dotnet / dotnet/runtime

TensorPrimitives.MinNumber(ReadOnlySpan<T>) incorrectly propagates NaN

Open
#133,346 2 comments 0 reactions 0 assignees View on GitHub
area-System.Numerics help wanted
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Description

`TensorPrimitives.MinNumber(ReadOnlySpan)` returns `NaN` when any element of the span is `NaN`, even when other elements are numbers.

This appears inconsistent with `MinNumber` semantics, where a numeric operand should be preferred over `NaN`.

### Reproduction Steps

```csharp
using System;
using System.Numerics.Tensors;

float[] values = [1f, float.NaN, 2f];

Console.WriteLine(float.MinNumber(1f, float.NaN));
Console.WriteLine(TensorPrimitives.MinNumber(values));
```

Output:

```text
1
NaN
```

### Expected behavior

`TensorPrimitives.MinNumber(values)` should return:

```text
1
```

A `NaN` should be ignored when another numeric value is available, consistent with `float.MinNumber` / `T.MinNumber`.

If all elements are `NaN`, returning `NaN` would be expected.

### Actual behavior

`TensorPrimitives.MinNumber(values)` returns `NaN` as soon as the reduction encounters a `NaN`.

### Regression?

Unknown

### Known Workarounds

Perform the reduction manually using `T.MinNumber`:

```csharp
T result = values[0];

for (int i = 1; i < values.Length; i++)
{
result = T.MinNumber(result, values[i]);
}
```

### Configuration

- .NET 10
- Appears to be independent of OS and architecture.

### Other information

The scalar reduction overload currently delegates to:

```csharp
MinMaxCore>(x)
```

However, `MinMaxCore` contains explicit `T.IsNaN(...)` checks that return the encountered `NaN` immediately. This prevents `MinNumberOperator`, which delegates to `T.MinNumber(x, y)`, from applying `MinNumber` semantics.

`MaxNumber(ReadOnlySpan)` appears to use the same reduction mechanism and may be affected by the equivalent issue.

Contributor guide

Open the contributing guide

Research direction

Start at the scalar TensorPrimitives.MinNumber(ReadOnlySpan) entry point and inspect MinMaxCore> together with the explicit T.IsNaN checks. Add regression coverage for mixed numeric/NaN input and all-NaN input, and check the equivalent MaxNumber reduction for the reported related behavior. Done means numeric values are preferred over NaN while an all-NaN span still returns NaN.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.