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

BitConverter.HalfToInt16Bits(Half) result comparison issue #82680

Closed
gcsizmadia opened this issue Feb 26, 2023 · 11 comments
Closed

BitConverter.HalfToInt16Bits(Half) result comparison issue #82680

gcsizmadia opened this issue Feb 26, 2023 · 11 comments
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Milestone

Comments

@gcsizmadia
Copy link

Description

I am playing around the negative zero number and I found an interesting thing while I used BitConverter.HalfToInt16(Half) method.

The two comparison gives different result

  • Compare the method result directly to 0.
  • Store the method result in a short variable then compare the variable to 0.

Reproduction Steps

Half half = (Half)(-0.0f);

// It will be -32768.
short bits = BitConverter.HalfToInt16Bits(half);

// It will be true.
bool isMethodResultGreaterThanOrEqualToZero = BitConverter.HalfToInt16Bits(half) >= 0;

// It will be false.
bool isVariableGreaterThanOrEqualToZero = bits >= 0;

Expected behavior

The expected behavior is that the two comparison method should have the same result: false

Actual behavior

  • When directly check if the method result is >= 0 then the comparison result will be true.
  • When storing the method result first in a variable and then check if the variable is >= 0 then the comparison result will be false.

Regression?

No response

Known Workarounds

No response

Configuration

  • Which version of .NET is the code running on?
    .NET 6.0.14 and .NET 7.0.3
  • What OS and version, and what distro if applicable?
    Windows 11 - Microsoft Windows [Version 10.0.22621.1265]
  • What is the architecture (x64, x86, ARM, ARM64)?
    x64
  • Do you know whether it is specific to that configuration?
    I don't know.

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 26, 2023
@Clockwork-Muse
Copy link
Contributor

I'm getting false for both.
Can you please write a small reproduction project that shows this issue?

@ghost
Copy link

ghost commented Feb 26, 2023

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I am playing around the negative zero number and I found an interesting thing while I used BitConverter.HalfToInt16(Half) method.

The two comparison gives different result

  • Compare the method result directly to 0.
  • Store the method result in a short variable then compare the variable to 0.

Reproduction Steps

Half half = (Half)(-0.0f);

// It will be -32768.
short bits = BitConverter.HalfToInt16Bits(half);

// It will be true.
bool isMethodResultGreaterThanOrEqualToZero = BitConverter.HalfToInt16Bits(half) >= 0;

// It will be false.
bool isVariableGreaterThanOrEqualToZero = bits >= 0;

Expected behavior

The expected behavior is that the two comparison method should have the same result: false

Actual behavior

  • When directly check if the method result is >= 0 then the comparison result will be true.
  • When storing the method result first in a variable and then check if the variable is >= 0 then the comparison result will be false.

Regression?

No response

Known Workarounds

No response

Configuration

  • Which version of .NET is the code running on?
    .NET 6.0.14 and .NET 7.0.3
  • What OS and version, and what distro if applicable?
    Windows 11 - Microsoft Windows [Version 10.0.22621.1265]
  • What is the architecture (x64, x86, ARM, ARM64)?
    x64
  • Do you know whether it is specific to that configuration?
    I don't know.

Other information

No response

Author: gcsizmadia
Assignees: -
Labels:

area-System.Numerics, untriaged

Milestone: -

@gcsizmadia
Copy link
Author

It seems that this issue applies only to .NET 6.0.14. In .NET 7.0.3 both values are false.

.NET 6.0.14

image
image

.NET 7.0.3

image

@gcsizmadia
Copy link
Author

I attached a .zip file with a simple console app that targets both .net6.0 and .net7.0.

BitConverterTest.zip

@KeterSCP
Copy link

It also has different output for Debug and Release in .NET 6.0.14

Debug:

-32768
True
False

Release:

32768
True
True

@teo-tsirpanis teo-tsirpanis added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-System.Numerics labels Feb 26, 2023
@ghost
Copy link

ghost commented Feb 26, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I am playing around the negative zero number and I found an interesting thing while I used BitConverter.HalfToInt16(Half) method.

The two comparison gives different result

  • Compare the method result directly to 0.
  • Store the method result in a short variable then compare the variable to 0.

Reproduction Steps

Half half = (Half)(-0.0f);

// It will be -32768.
short bits = BitConverter.HalfToInt16Bits(half);

// It will be true.
bool isMethodResultGreaterThanOrEqualToZero = BitConverter.HalfToInt16Bits(half) >= 0;

// It will be false.
bool isVariableGreaterThanOrEqualToZero = bits >= 0;

Expected behavior

The expected behavior is that the two comparison method should have the same result: false

Actual behavior

  • When directly check if the method result is >= 0 then the comparison result will be true.
  • When storing the method result first in a variable and then check if the variable is >= 0 then the comparison result will be false.

Regression?

No response

Known Workarounds

No response

Configuration

  • Which version of .NET is the code running on?
    .NET 6.0.14 and .NET 7.0.3
  • What OS and version, and what distro if applicable?
    Windows 11 - Microsoft Windows [Version 10.0.22621.1265]
  • What is the architecture (x64, x86, ARM, ARM64)?
    x64
  • Do you know whether it is specific to that configuration?
    I don't know.

Other information

No response

Author: gcsizmadia
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged

Milestone: -

@JulieLeeMSFT
Copy link
Member

@gcsizmadia, is there product impact with .NET 6.0.14? Can you work with .NET 7.0.3?

It seems that this issue applies only to .NET 6.0.14.

@gcsizmadia
Copy link
Author

gcsizmadia commented Mar 1, 2023

@JulieLeeMSFT, I'm working on a class library (nuget package) that targets both net6.0 and net7.0 as well and its functions must work on both, especially because .NET 6 is an LTS version that will stay longer with us than .NET 7.

So unless there is a workaround that can be applied to net6.0 target, it is a product impact.

@jakobbotsch
Copy link
Member

This sounds like the same issue as #61359 that was fixed in .NET 7+ by #64881. I think we can backport that fix to .NET 6.

@JulieLeeMSFT
Copy link
Member

Sounds good. Please check if it solves this problem and backport it.

This sounds like the same issue as #61359 that was fixed in .NET 7+ by #64881. I think we can backport that fix to .NET 6.

@JulieLeeMSFT JulieLeeMSFT added this to the 8.0.0 milestone Mar 1, 2023
@JulieLeeMSFT JulieLeeMSFT removed the untriaged New issue has not been triaged by the area owner label Mar 1, 2023
@jakobbotsch
Copy link
Member

This was backported and the fix is available in 6.0.16 that was released on April 11th.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

No branches or pull requests

7 participants