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: ToDouble, ToSingle, Int64BitsToDouble, Int32BitsToDouble #2977

Open
peteroupc opened this issue Aug 11, 2019 · 3 comments
Open
Labels
area-System.Runtime Pri3 Indicates issues/PRs that are low priority untriaged New issue has not been triaged by the area owner

Comments

@peteroupc
Copy link

Link to article:
https://docs.microsoft.com/en-us/dotnet/api/system.bitconverter.todouble?view=netstandard-2.0

Problem:

Mention that it might not be possible to use these methods to produce what are so-called _signaling NaN_s in x86, x64, and certain other instruction set architectures. A signaling NaN is an NaN with the most significant bit of the mantissa area clear (as opposed to a quiet NaN where that bit is set). An example of a signaling NaN is as follows (with little-endian byte ordering):

new byte[]{ 1, 0, 0, 0, 0, 0, 0xf0, 0x7f };

At least in x86, using ToDouble and converting the resulting double back will convert the signaling NaN to a quiet NaN as follows:

new byte[]{ 1, 0, 0, 0, 0, 0, 0xf8, 0x7f };

This can be an issue if the application works with binary serialization formats that store double or float values in the form of the bits that make them up, because converting those bits to double or float with these BitConverter methods may make round-tripping that double or float not always possible.

@dotnet-bot dotnet-bot added the untriaged New issue has not been triaged by the area owner label Aug 11, 2019
@PRMerger13 PRMerger13 added the Pri3 Indicates issues/PRs that are low priority label Nov 11, 2020
@eiriktsarpalis
Copy link
Member

Tagging @pgovind @tannergooding for triage.

@tannergooding
Copy link
Member

Thanks! This repros on .NET Core using:

var xb = new byte[] { 1, 0, 0, 0, 0, 0, 0xf0, 0x7f };
var yb = new byte[] { 1, 0, 0, 0, 0, 0, 0xf8, 0x7f };

var x = BitConverter.ToDouble(xb);
var y = BitConverter.ToDouble(yb);

Console.WriteLine(Environment.Is64BitProcess);
Console.WriteLine($"{x}    {BitConverter.DoubleToInt64Bits(x):X16}");
Console.WriteLine($"{y}    {BitConverter.DoubleToInt64Bits(y):X16}");

I'd like to investigate a bit more and determine "why" the value is being changed (I expect it might be due to the x87 FPU stack).

@peteroupc
Copy link
Author

Another curiosity I found with respect to NaN.

In .NET, Double.NaN and Single.NaN have the following bit patterns:

new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0xff }
new byte[]{ 0, 0, c0, ff }

Where the so-called "sign bit" of the value (topmost bit of the last byte) is set. Whereas in Java, for example, the equivalent Double.NaN and Float.NaN have that bit clear:

new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0x7f }
new byte[]{ 0, 0, c0, 7f }

This shows once again the multi-faced nature of NaN.

Related: WebAssembly/interface-types#134

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Runtime Pri3 Indicates issues/PRs that are low priority untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

5 participants