Skip to content
2 changes: 1 addition & 1 deletion src/libraries/System.Private.CoreLib/src/System/Half.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,7 @@ public static int ILogB(Half x)
}

Debug.Assert(IsSubnormal(x));
return MinExponent - (BitOperations.LeadingZeroCount(x.TrailingSignificand) - BiasedExponentLength);
return MinExponent - (ushort.LeadingZeroCount(x.TrailingSignificand) - BiasedExponentLength);
}

return x.Exponent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public readonly struct BFloat16
internal const sbyte MinExponent = -126;
internal const sbyte MaxExponent = +127;

internal const ushort MinTrailingSignificand = 0x0000;
internal const ushort MaxTrailingSignificand = 0x007F;
internal const byte MinTrailingSignificand = 0x00;
internal const byte MaxTrailingSignificand = 0x7F;

internal const int TrailingSignificandLength = 7;
internal const int SignificandLength = TrailingSignificandLength + 1;
Expand Down Expand Up @@ -124,7 +124,7 @@ internal byte Significand
}
}

internal ushort TrailingSignificand
internal byte TrailingSignificand
{
get
{
Expand All @@ -138,9 +138,9 @@ internal static byte ExtractBiasedExponentFromBits(ushort bits)
return (byte)((bits >> BiasedExponentShift) & ShiftedBiasedExponentMask);
}

internal static ushort ExtractTrailingSignificandFromBits(ushort bits)
internal static byte ExtractTrailingSignificandFromBits(ushort bits)
{
return (ushort)(bits & TrailingSignificandMask);
return (byte)(bits & TrailingSignificandMask);
}

// INumberBase
Expand Down Expand Up @@ -877,12 +877,12 @@ public static bool IsPow2(BFloat16 value)
}

byte biasedExponent = ExtractBiasedExponentFromBits(bits);
ushort trailingSignificand = ExtractTrailingSignificandFromBits(bits);
byte trailingSignificand = ExtractTrailingSignificandFromBits(bits);

if (biasedExponent == MinBiasedExponent)
{
// Subnormal values have 1 bit set when they're powers of 2
return ushort.PopCount(trailingSignificand) == 1;
return byte.PopCount(trailingSignificand) == 1;
}
else if (biasedExponent == MaxBiasedExponent)
{
Expand Down Expand Up @@ -1191,7 +1191,7 @@ public static int ILogB(BFloat16 x)
}

Debug.Assert(IsSubnormal(x));
return MinExponent - (BitOperations.LeadingZeroCount(x.TrailingSignificand) - BiasedExponentLength);
return MinExponent - byte.LeadingZeroCount(x.TrailingSignificand);
}

return x.Exponent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2244,5 +2244,30 @@ public static void RadiansToDegreesTest(Half value, Half expectedResult, Half al
AssertExtensions.Equal(-expectedResult, Half.RadiansToDegrees(-value), allowedVariance);
AssertExtensions.Equal(+expectedResult, Half.RadiansToDegrees(+value), allowedVariance);
}

[Theory]
[InlineData(float.PositiveInfinity, int.MaxValue)]
[InlineData(float.NaN, int.MaxValue)]
[InlineData(0.0f, int.MinValue)]
[InlineData(1.0f, 0)]
[InlineData(2.0f, 1)]
[InlineData(4.0f, 2)]
[InlineData(0.5f, -1)]
public static void ILogB(float value, int expectedResult)
{
Assert.Equal(expectedResult, Half.ILogB((Half)value));
}

[Fact]
public static void ILogB_Subnormal()
{
// Half.Epsilon is the smallest positive subnormal value
// Its ILogB should be -24 (floor(log2(5.9604645E-08)))
Assert.Equal(-24, Half.ILogB(Half.Epsilon));

// Test another subnormal value: 0x0200 (half of max subnormal)
Half subnormal = BitConverter.UInt16BitsToHalf(0x0200);
Assert.Equal(-15, Half.ILogB(subnormal));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2271,6 +2271,31 @@ public static void RadiansToDegreesTest(BFloat16 value, BFloat16 expectedResult,
AssertEqual(+expectedResult, BFloat16.RadiansToDegrees(+value), allowedVariance);
}

[Theory]
[InlineData(float.PositiveInfinity, int.MaxValue)]
[InlineData(float.NaN, int.MaxValue)]
[InlineData(0.0f, int.MinValue)]
[InlineData(1.0f, 0)]
[InlineData(2.0f, 1)]
[InlineData(4.0f, 2)]
[InlineData(0.5f, -1)]
public static void ILogB(float value, int expectedResult)
{
Assert.Equal(expectedResult, BFloat16.ILogB((BFloat16)value));
}

[Fact]
public static void ILogB_Subnormal()
{
// BFloat16.Epsilon is the smallest positive subnormal value
// Its ILogB should be -133
Assert.Equal(-133, BFloat16.ILogB(BFloat16.Epsilon));

// Test another subnormal value: 0x0040 (half of max subnormal)
BFloat16 subnormal = BitConverter.UInt16BitsToBFloat16(0x0040);
Assert.Equal(-127, BFloat16.ILogB(subnormal));
}

public static IEnumerable<object[]> TryWriteSignificandBigEndianTest_TestData() =>
[
[BFloat16.NegativeInfinity, 1, new byte[] { 0x80 }],
Expand Down