未验证 提交 36a7e76f 编写于 作者: M MichalPetryka 提交者: GitHub

Add unsigned variants for BitConverter float bit APIs (#53784)

* Add unsigned variants for BitConverter bit APIs

Adds DoubleToUInt64Bits, UInt64BitsToDouble, SingleToUInt32Bits,
UInt32BitsToSingle, HalfToUInt16Bits and UInt16BitsToHalf.

Implementations were based on existing signed integer variants.

Convert usages of existing APIs to unsigned variants when appropriate.

Fix #36469

* Revert comment change

Reverted a comment change made in the existing code by mistake.

* Use existing code for implementations

Use the existing signed methods with a cast, less code with the same codegen.

* Cast correction

Corrected the type used in a cast.
上级 3ead4ac1
......@@ -198,7 +198,7 @@ public Variant(float val)
{
_objref = null;
_flags = CV_R4;
_data = (uint)BitConverter.SingleToInt32Bits(val);
_data = BitConverter.SingleToUInt32Bits(val);
}
public Variant(double val)
......@@ -328,7 +328,7 @@ CVType switch
CV_U4 => (uint)_data,
CV_I8 => _data,
CV_U8 => (ulong)_data,
CV_R4 => BitConverter.Int32BitsToSingle((int)_data),
CV_R4 => BitConverter.UInt32BitsToSingle((uint)_data),
CV_R8 => BitConverter.Int64BitsToDouble(_data),
CV_DATETIME => new DateTime(_data),
CV_TIMESPAN => new TimeSpan(_data),
......
......@@ -410,7 +410,7 @@ public void TestParserDouble_SpecificPowers(int b, int start, int end)
for (int i = start; i != end; i++)
{
double d = Math.Pow(b, i);
ulong bits = (ulong)BitConverter.DoubleToInt64Bits(d);
ulong bits = BitConverter.DoubleToUInt64Bits(d);
TestRoundTripDouble(bits - 1);
TestRoundTripDouble(bits);
......@@ -594,7 +594,7 @@ public void TestParserSingle_SpecificPowers(int b, int start, int end)
for (int i = start; i != end; ++i)
{
float f = MathF.Pow(b, i);
uint bits = (uint)BitConverter.SingleToInt32Bits(f);
uint bits = BitConverter.SingleToUInt32Bits(f);
TestRoundTripSingle(bits - 1);
TestRoundTripSingle(bits);
......@@ -604,7 +604,7 @@ public void TestParserSingle_SpecificPowers(int b, int start, int end)
private void CheckOneDouble(string s, ulong expectedBits)
{
CheckOneDouble(s, BitConverter.Int64BitsToDouble((long)(expectedBits)));
CheckOneDouble(s, BitConverter.UInt64BitsToDouble(expectedBits));
}
private void CheckOneDouble(string s, double expected)
......@@ -620,7 +620,7 @@ private void CheckOneDouble(string s, double expected)
private void CheckOneSingle(string s, uint expectedBits)
{
CheckOneSingle(s, BitConverter.Int32BitsToSingle((int)(expectedBits)));
CheckOneSingle(s, BitConverter.UInt32BitsToSingle(expectedBits));
}
private void CheckOneSingle(string s, float expected)
......@@ -642,7 +642,7 @@ private void TestRoundTripDouble(double d)
private void TestRoundTripDouble(ulong bits)
{
double d = BitConverter.Int64BitsToDouble((long)(bits));
double d = BitConverter.UInt64BitsToDouble(bits);
if (double.IsFinite(d))
{
......@@ -659,7 +659,7 @@ private void TestRoundTripSingle(float d)
private void TestRoundTripSingle(uint bits)
{
float d = BitConverter.Int32BitsToSingle((int)(bits));
float d = BitConverter.UInt32BitsToSingle(bits);
if (float.IsFinite(d))
{
......
......@@ -857,5 +857,59 @@ public static unsafe Half Int16BitsToHalf(short value)
{
return *(Half*)&value;
}
/// <summary>
/// Converts the specified double-precision floating point number to a 64-bit unsigned integer.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A 64-bit unsigned integer whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe ulong DoubleToUInt64Bits(double value) => (ulong)DoubleToInt64Bits(value);
/// <summary>
/// Converts the specified 64-bit unsigned integer to a double-precision floating point number.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A double-precision floating point number whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe double UInt64BitsToDouble(ulong value) => Int64BitsToDouble((long)value);
/// <summary>
/// Converts the specified single-precision floating point number to a 32-bit unsigned integer.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A 32-bit unsigned integer whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe uint SingleToUInt32Bits(float value) => (uint)SingleToInt32Bits(value);
/// <summary>
/// Converts the specified 32-bit unsigned integer to a single-precision floating point number.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A single-precision floating point number whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float UInt32BitsToSingle(uint value) => Int32BitsToSingle((int)value);
/// <summary>
/// Converts the specified half-precision floating point number to a 16-bit unsigned integer.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A 16-bit unsigned integer whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe ushort HalfToUInt16Bits(Half value) => (ushort)HalfToInt16Bits(value);
/// <summary>
/// Converts the specified 16-bit unsigned integer to a half-precision floating point number.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>A half-precision floating point number whose bits are identical to <paramref name="value"/>.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Half UInt16BitsToHalf(ushort value) => Int16BitsToHalf((short)value);
}
}
......@@ -491,7 +491,7 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
{
const int SingleMaxExponent = 0xFF;
uint floatInt = (uint)BitConverter.SingleToInt32Bits(value);
uint floatInt = BitConverter.SingleToUInt32Bits(value);
bool sign = (floatInt & float.SignMask) >> float.SignShift != 0;
int exp = (int)(floatInt & float.ExponentMask) >> float.ExponentShift;
uint sig = floatInt & float.SignificandMask;
......@@ -519,7 +519,7 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
{
const int DoubleMaxExponent = 0x7FF;
ulong doubleInt = (ulong)BitConverter.DoubleToInt64Bits(value);
ulong doubleInt = BitConverter.DoubleToUInt64Bits(value);
bool sign = (doubleInt & double.SignMask) >> double.SignShift != 0;
int exp = (int)((doubleInt & double.ExponentMask) >> double.ExponentShift);
ulong sig = doubleInt & double.SignificandMask;
......@@ -561,7 +561,7 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
{
if (sig == 0)
{
return BitConverter.Int32BitsToSingle((int)(sign ? float.SignMask : 0)); // Positive / Negative zero
return BitConverter.UInt32BitsToSingle(sign ? float.SignMask : 0); // Positive / Negative zero
}
(exp, sig) = NormSubnormalF16Sig(sig);
exp -= 1;
......@@ -589,7 +589,7 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
{
if (sig == 0)
{
return BitConverter.Int64BitsToDouble((long)(sign ? double.SignMask : 0)); // Positive / Negative zero
return BitConverter.UInt64BitsToDouble(sign ? double.SignMask : 0); // Positive / Negative zero
}
(exp, sig) = NormSubnormalF16Sig(sig);
exp -= 1;
......@@ -621,7 +621,7 @@ private static Half CreateHalfNaN(bool sign, ulong significand)
uint signInt = (sign ? 1U : 0U) << SignShift;
uint sigInt = (uint)(significand >> 54);
return BitConverter.Int16BitsToHalf((short)(signInt | NaNBits | sigInt));
return BitConverter.UInt16BitsToHalf((ushort)(signInt | NaNBits | sigInt));
}
private static ushort RoundPackToHalf(bool sign, short exp, ushort sig)
......@@ -670,7 +670,7 @@ private static float CreateSingleNaN(bool sign, ulong significand)
uint signInt = (sign ? 1U : 0U) << float.SignShift;
uint sigInt = (uint)(significand >> 41);
return BitConverter.Int32BitsToSingle((int)(signInt | NaNBits | sigInt));
return BitConverter.UInt32BitsToSingle(signInt | NaNBits | sigInt);
}
private static double CreateDoubleNaN(bool sign, ulong significand)
......@@ -680,14 +680,14 @@ private static double CreateDoubleNaN(bool sign, ulong significand)
ulong signInt = (sign ? 1UL : 0UL) << double.SignShift;
ulong sigInt = significand >> 12;
return BitConverter.Int64BitsToDouble((long)(signInt | NaNBits | sigInt));
return BitConverter.UInt64BitsToDouble(signInt | NaNBits | sigInt);
}
private static float CreateSingle(bool sign, byte exp, uint sig)
=> BitConverter.Int32BitsToSingle((int)(((sign ? 1U : 0U) << float.SignShift) + ((uint)exp << float.ExponentShift) + sig));
=> BitConverter.UInt32BitsToSingle(((sign ? 1U : 0U) << float.SignShift) + ((uint)exp << float.ExponentShift) + sig);
private static double CreateDouble(bool sign, ushort exp, ulong sig)
=> BitConverter.Int64BitsToDouble((long)(((sign ? 1UL : 0UL) << double.SignShift) + ((ulong)exp << double.ExponentShift) + sig));
=> BitConverter.UInt64BitsToDouble(((sign ? 1UL : 0UL) << double.SignShift) + ((ulong)exp << double.ExponentShift) + sig);
#endregion
}
......
......@@ -1175,7 +1175,7 @@ public static double Round(double a)
// This is based on the 'Berkeley SoftFloat Release 3e' algorithm
ulong bits = (ulong)BitConverter.DoubleToInt64Bits(a);
ulong bits = BitConverter.DoubleToUInt64Bits(a);
int exponent = double.ExtractExponentFromBits(bits);
if (exponent <= 0x03FE)
......@@ -1231,7 +1231,7 @@ public static double Round(double a)
bits &= ~roundBitsMask;
}
return BitConverter.Int64BitsToDouble((long)bits);
return BitConverter.UInt64BitsToDouble(bits);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
......
......@@ -325,7 +325,7 @@ public static float Round(float x)
// This is based on the 'Berkeley SoftFloat Release 3e' algorithm
uint bits = (uint)BitConverter.SingleToInt32Bits(x);
uint bits = BitConverter.SingleToUInt32Bits(x);
int exponent = float.ExtractExponentFromBits(bits);
if (exponent <= 0x7E)
......@@ -381,7 +381,7 @@ public static float Round(float x)
bits &= ~roundBitsMask;
}
return BitConverter.Int32BitsToSingle((int)bits);
return BitConverter.UInt32BitsToSingle(bits);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
......
......@@ -2629,7 +2629,7 @@ private static uint Int64DivMod1E9(ref ulong value)
private static ulong ExtractFractionAndBiasedExponent(double value, out int exponent)
{
ulong bits = (ulong)(BitConverter.DoubleToInt64Bits(value));
ulong bits = BitConverter.DoubleToUInt64Bits(value);
ulong fraction = (bits & 0xFFFFFFFFFFFFF);
exponent = ((int)(bits >> 52) & 0x7FF);
......@@ -2661,7 +2661,7 @@ private static ulong ExtractFractionAndBiasedExponent(double value, out int expo
private static ushort ExtractFractionAndBiasedExponent(Half value, out int exponent)
{
ushort bits = (ushort)BitConverter.HalfToInt16Bits(value);
ushort bits = BitConverter.HalfToUInt16Bits(value);
ushort fraction = (ushort)(bits & 0x3FF);
exponent = ((int)(bits >> 10) & 0x1F);
......@@ -2693,7 +2693,7 @@ private static ushort ExtractFractionAndBiasedExponent(Half value, out int expon
private static uint ExtractFractionAndBiasedExponent(float value, out int exponent)
{
uint bits = (uint)(BitConverter.SingleToInt32Bits(value));
uint bits = BitConverter.SingleToUInt32Bits(value);
uint fraction = (bits & 0x7FFFFF);
exponent = ((int)(bits >> 23) & 0xFF);
......
......@@ -388,7 +388,7 @@ private static ulong NumberToDoubleFloatingPointBits(ref NumberBuffer number, in
result *= scale;
}
return (ulong)(BitConverter.DoubleToInt64Bits(result));
return BitConverter.DoubleToUInt64Bits(result);
}
return NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent);
......@@ -450,7 +450,7 @@ private static ushort NumberToHalfFloatingPointBits(ref NumberBuffer number, in
result *= scale;
}
return (ushort)(BitConverter.HalfToInt16Bits((Half)result));
return BitConverter.HalfToUInt16Bits((Half)result);
}
if ((totalDigits <= 15) && (fastExponent <= 22))
......@@ -467,7 +467,7 @@ private static ushort NumberToHalfFloatingPointBits(ref NumberBuffer number, in
result *= scale;
}
return (ushort)(BitConverter.HalfToInt16Bits((Half)(result)));
return BitConverter.HalfToUInt16Bits((Half)(result));
}
return (ushort)NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent);
......@@ -529,7 +529,7 @@ private static uint NumberToSingleFloatingPointBits(ref NumberBuffer number, in
result *= scale;
}
return (uint)(BitConverter.SingleToInt32Bits(result));
return BitConverter.SingleToUInt32Bits(result);
}
if ((totalDigits <= 15) && (fastExponent <= 22))
......@@ -546,7 +546,7 @@ private static uint NumberToSingleFloatingPointBits(ref NumberBuffer number, in
result *= scale;
}
return (uint)(BitConverter.SingleToInt32Bits((float)(result)));
return BitConverter.SingleToUInt32Bits((float)(result));
}
return (uint)NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent);
......
......@@ -2143,7 +2143,7 @@ internal static double NumberToDouble(ref NumberBuffer number)
else
{
ulong bits = NumberToDoubleFloatingPointBits(ref number, in FloatingPointInfo.Double);
result = BitConverter.Int64BitsToDouble((long)(bits));
result = BitConverter.UInt64BitsToDouble(bits);
}
return number.IsNegative ? -result : result;
......@@ -2187,7 +2187,7 @@ internal static float NumberToSingle(ref NumberBuffer number)
else
{
uint bits = NumberToSingleFloatingPointBits(ref number, in FloatingPointInfo.Single);
result = BitConverter.Int32BitsToSingle((int)(bits));
result = BitConverter.UInt32BitsToSingle(bits);
}
return number.IsNegative ? -result : result;
......
......@@ -21,12 +21,12 @@ internal static class XPathConvert
{
public static uint DblHi(double dbl)
{
return (uint)(BitConverter.DoubleToInt64Bits(dbl) >> 32);
return (uint)(BitConverter.DoubleToUInt64Bits(dbl) >> 32);
}
public static uint DblLo(double dbl)
{
return unchecked((uint)BitConverter.DoubleToInt64Bits(dbl));
return unchecked((uint)BitConverter.DoubleToUInt64Bits(dbl));
}
// Returns true if value is infinite or NaN (exponent bits are all ones)
......@@ -659,7 +659,7 @@ private void Mul(ref BigNumber numOp)
AddU(ref dblHi, 1);
}
}
return BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo);
return BitConverter.UInt64BitsToDouble((ulong)dblHi << 32 | dblLo);
}
// Lop off the integer part and return it.
......@@ -1112,7 +1112,7 @@ public static void DblToRgbPrecise(double dbl, byte[] mantissa, out int exponent
dblHi = DblHi(dblT);
dblHi &= 0x000FFFFF;
dblHi |= 0x3FF00000;
dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | DblLo(dblT));
dblT = BitConverter.UInt64BitsToDouble((ulong)dblHi << 32 | DblLo(dblT));
// Adjust wExp2 because we don't have the implicit bit.
wExp2++;
......@@ -1123,7 +1123,7 @@ public static void DblToRgbPrecise(double dbl, byte[] mantissa, out int exponent
// First multiply by a power of 2 to get a normalized value.
dblHi &= 0x000FFFFF;
dblHi |= 0x3FF00000;
dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo);
dblT = BitConverter.UInt64BitsToDouble((ulong)dblHi << 32 | dblLo);
// This is the power of 2.
w1 = wExp2 + 52;
......@@ -2307,7 +2307,7 @@ public uint DivRem(BigInteger bi)
}
}
}
return BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo);
return BitConverter.UInt64BitsToDouble((ulong)dblHi << 32 | dblLo);
}
#endif
};
......
......@@ -295,5 +295,35 @@ public static void HalfToInt16Bits()
Half roundtripped = BitConverter.Int16BitsToHalf(result);
Assert.Equal(input, roundtripped);
}
[Fact]
public static void DoubleToUInt64Bits()
{
double input = 123456.3234;
ulong result = BitConverter.DoubleToUInt64Bits(input);
Assert.Equal(4683220267154373240UL, result);
double roundtripped = BitConverter.UInt64BitsToDouble(result);
Assert.Equal(input, roundtripped);
}
[Fact]
public static void SingleToUInt32Bits()
{
float input = 12345.63f;
uint result = BitConverter.SingleToUInt32Bits(input);
Assert.Equal(1178658437U, result);
float roundtripped = BitConverter.UInt32BitsToSingle(result);
Assert.Equal(input, roundtripped);
}
[Fact]
public static void HalfToUInt16Bits()
{
Half input = (Half)12.34;
ushort result = BitConverter.HalfToUInt16Bits(input);
Assert.Equal((ushort)18988, result);
Half roundtripped = BitConverter.UInt16BitsToHalf(result);
Assert.Equal(input, roundtripped);
}
}
}
......@@ -600,6 +600,18 @@ public static partial class BitConverter
public static float Int32BitsToSingle(int value) { throw null; }
public static double Int64BitsToDouble(long value) { throw null; }
public static int SingleToInt32Bits(float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static ulong DoubleToUInt64Bits(double value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static double UInt64BitsToDouble(ulong value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static uint SingleToUInt32Bits(float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static float UInt32BitsToSingle(uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static ushort HalfToUInt16Bits(System.Half value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static System.Half UInt16BitsToHalf(ushort value) { throw null; }
public static bool ToBoolean(byte[] value, int startIndex) { throw null; }
public static bool ToBoolean(System.ReadOnlySpan<byte> value) { throw null; }
public static char ToChar(byte[] value, int startIndex) { throw null; }
......
......@@ -13,11 +13,6 @@ public class DoubleTests
{
// NOTE: Consider duplicating any tests added here in SingleTests.cs
private static ulong DoubleToUInt64Bits(double value)
{
return (ulong)(BitConverter.DoubleToInt64Bits(value));
}
[Theory]
[InlineData("a")]
[InlineData(234.0f)]
......@@ -103,7 +98,7 @@ public static void Ctor_Value()
public static void Epsilon()
{
Assert.Equal(4.9406564584124654E-324, double.Epsilon);
Assert.Equal(0x00000000_00000001u, DoubleToUInt64Bits(double.Epsilon));
Assert.Equal(0x00000000_00000001u, BitConverter.DoubleToUInt64Bits(double.Epsilon));
}
[Theory]
......@@ -221,28 +216,28 @@ public static void IsPositiveInfinity(double d, bool expected)
public static void MaxValue()
{
Assert.Equal(1.7976931348623157E+308, double.MaxValue);
Assert.Equal(0x7FEFFFFF_FFFFFFFFu, DoubleToUInt64Bits(double.MaxValue));
Assert.Equal(0x7FEFFFFF_FFFFFFFFu, BitConverter.DoubleToUInt64Bits(double.MaxValue));
}
[Fact]
public static void MinValue()
{
Assert.Equal(-1.7976931348623157E+308, double.MinValue);
Assert.Equal(0xFFEFFFFF_FFFFFFFFu, DoubleToUInt64Bits(double.MinValue));
Assert.Equal(0xFFEFFFFF_FFFFFFFFu, BitConverter.DoubleToUInt64Bits(double.MinValue));
}
[Fact]
public static void NaN()
{
Assert.Equal(0.0 / 0.0, double.NaN);
Assert.Equal(0xFFF80000_00000000u, DoubleToUInt64Bits(double.NaN));
Assert.Equal(0xFFF80000_00000000u, BitConverter.DoubleToUInt64Bits(double.NaN));
}
[Fact]
public static void NegativeInfinity()
{
Assert.Equal(-1.0 / 0.0, double.NegativeInfinity);
Assert.Equal(0xFFF00000_00000000u, DoubleToUInt64Bits(double.NegativeInfinity));
Assert.Equal(0xFFF00000_00000000u, BitConverter.DoubleToUInt64Bits(double.NegativeInfinity));
}
public static IEnumerable<object[]> Parse_Valid_TestData()
......@@ -474,7 +469,7 @@ public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatP
public static void PositiveInfinity()
{
Assert.Equal(1.0 / 0.0, double.PositiveInfinity);
Assert.Equal(0x7FF00000_00000000u, DoubleToUInt64Bits(double.PositiveInfinity));
Assert.Equal(0x7FF00000_00000000u, BitConverter.DoubleToUInt64Bits(double.PositiveInfinity));
}
public static IEnumerable<object[]> ToString_TestData()
......
......@@ -15,11 +15,6 @@ public partial class SingleTests
{
// NOTE: Consider duplicating any tests added here in DoubleTests.cs
private static uint SingleToUInt32Bits(float value)
{
return Unsafe.As<float, uint>(ref value);
}
[Theory]
[InlineData("a")]
[InlineData(234.0)]
......@@ -105,7 +100,7 @@ public static void Ctor_Value()
public static void Epsilon()
{
Assert.Equal(1.40129846E-45f, float.Epsilon);
Assert.Equal(0x00000001u, SingleToUInt32Bits(float.Epsilon));
Assert.Equal(0x00000001u, BitConverter.SingleToUInt32Bits(float.Epsilon));
}
[Theory]
......@@ -223,28 +218,28 @@ public static void IsPositiveInfinity(float d, bool expected)
public static void MaxValue()
{
Assert.Equal(3.40282347E+38f, float.MaxValue);
Assert.Equal(0x7F7FFFFFu, SingleToUInt32Bits(float.MaxValue));
Assert.Equal(0x7F7FFFFFu, BitConverter.SingleToUInt32Bits(float.MaxValue));
}
[Fact]
public static void MinValue()
{
Assert.Equal(-3.40282347E+38f, float.MinValue);
Assert.Equal(0xFF7FFFFFu, SingleToUInt32Bits(float.MinValue));
Assert.Equal(0xFF7FFFFFu, BitConverter.SingleToUInt32Bits(float.MinValue));
}
[Fact]
public static void NaN()
{
Assert.Equal(0.0f / 0.0f, float.NaN);
Assert.Equal(0xFFC00000u, SingleToUInt32Bits(float.NaN));
Assert.Equal(0xFFC00000u, BitConverter.SingleToUInt32Bits(float.NaN));
}
[Fact]
public static void NegativeInfinity()
{
Assert.Equal(-1.0f / 0.0f, float.NegativeInfinity);
Assert.Equal(0xFF800000u, SingleToUInt32Bits(float.NegativeInfinity));
Assert.Equal(0xFF800000u, BitConverter.SingleToUInt32Bits(float.NegativeInfinity));
}
public static IEnumerable<object[]> Parse_Valid_TestData()
......@@ -479,7 +474,7 @@ public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatP
public static void PositiveInfinity()
{
Assert.Equal(1.0f / 0.0f, float.PositiveInfinity);
Assert.Equal(0x7F800000u, SingleToUInt32Bits(float.PositiveInfinity));
Assert.Equal(0x7F800000u, BitConverter.SingleToUInt32Bits(float.PositiveInfinity));
}
public static IEnumerable<object[]> ToString_TestData()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册