diff --git a/eng/Versions.props b/eng/Versions.props index 53f4052e9f3189..9453847bc3013b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -49,7 +49,7 @@ - 4.3.0-2.22270.2 + 4.3.0-2.22270.4 2.0.0-preview.4.22252.4 diff --git a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs index ae94eb660fdd82..287c410e16dcd9 100644 --- a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs +++ b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs @@ -562,6 +562,16 @@ public static MethodDesc TryResolveConstraintMethodApprox(this TypeDesc constrai method = null; } + // Default implementation logic, which only kicks in for default implementations when looking up on an exact interface target + if (isStaticVirtualMethod && method == null && !genInterfaceMethod.IsAbstract && !constrainedType.IsCanonicalSubtype(CanonicalFormKind.Any)) + { + MethodDesc exactInterfaceMethod = genInterfaceMethod; + if (genInterfaceMethod.OwningType != interfaceType) + exactInterfaceMethod = context.GetMethodForInstantiatedType( + genInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceType); + method = exactInterfaceMethod; + } + if (method == null) { // Fall back to VSD diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs index 3da65b1530ed24..88f726c26d0424 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs @@ -1438,6 +1438,10 @@ public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultCo if (instantiatedConstrainedMethod.Signature.IsStatic) { implMethod = instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(instantiatedConstrainedMethod); + if (implMethod == null && !instantiatedConstrainedMethod.IsAbstract) + { + implMethod = instantiatedConstrainedMethod; + } } else { @@ -1451,7 +1455,6 @@ public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultCo // AOT use of this generic lookup is restricted to finding methods on valuetypes (runtime usage of this slot in universal generics is more flexible) Debug.Assert(instantiatedConstraintType.IsValueType || (instantiatedConstrainedMethod.OwningType.IsInterface && instantiatedConstrainedMethod.Signature.IsStatic)); - Debug.Assert(!instantiatedConstraintType.IsValueType || implMethod.OwningType == instantiatedConstraintType); if (implMethod.Signature.IsStatic) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index c07d679f9be02a..c0850138a7207f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -424,7 +424,8 @@ private void ImportCall(ILOpcode opcode, int token) methodAfterConstraintResolution = directMethod; - Debug.Assert(!methodAfterConstraintResolution.OwningType.IsInterface); + Debug.Assert(!methodAfterConstraintResolution.OwningType.IsInterface + || methodAfterConstraintResolution.Signature.IsStatic); resolvedConstraint = true; exactType = constrained; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 1896db9fae8274..141b98bf5d93e5 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1203,7 +1203,8 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO methodAfterConstraintResolution = directMethod; - Debug.Assert(!methodAfterConstraintResolution.OwningType.IsInterface); + Debug.Assert(!methodAfterConstraintResolution.OwningType.IsInterface + || methodAfterConstraintResolution.Signature.IsStatic); resolvedConstraint = true; pResult->thisTransform = CORINFO_THIS_TRANSFORM.CORINFO_NO_THIS_TRANSFORM; diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 1814ff4de269c0..5aae97dd5cb67d 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -8067,7 +8067,7 @@ MethodTable::ResolveVirtualStaticMethod(MethodTable* pInterfaceType, MethodDesc* } } - // Default implementation logic, which only kicks in for default implementations when lookin up on an exact interface target + // Default implementation logic, which only kicks in for default implementations when looking up on an exact interface target if (!pInterfaceMD->IsAbstract() && !(this == g_pCanonMethodTableClass) && !IsSharedByGenericInstantiations()) { return pInterfaceMD->FindOrCreateAssociatedMethodDesc(pInterfaceMD, pInterfaceType, FALSE, pInterfaceMD->GetMethodInstantiation(), FALSE); diff --git a/src/libraries/Common/tests/System/GenericMathHelpers.cs b/src/libraries/Common/tests/System/GenericMathHelpers.cs index b2ce6e4896fe18..c6bbb21304f2ed 100644 --- a/src/libraries/Common/tests/System/GenericMathHelpers.cs +++ b/src/libraries/Common/tests/System/GenericMathHelpers.cs @@ -358,9 +358,6 @@ public static TSelf CreateTruncating(TOther value) public static TSelf Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider provider) => TSelf.Parse(s, style, provider); - public static bool TryCreate(TOther value, out TSelf result) - where TOther : INumberBase => TSelf.TryCreate(value, out result); - public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out TSelf result) => TSelf.TryParse(s, style, provider, out result); public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider provider, out TSelf result) => TSelf.TryParse(s, style, provider, out result); diff --git a/src/libraries/System.Private.CoreLib/src/System/Byte.cs b/src/libraries/System.Private.CoreLib/src/System/Byte.cs index 0104da49a46dac..f8bf9347ec5c16 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Byte.cs @@ -531,476 +531,475 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static byte INumberBase.Abs(byte value) => value; - /// + /// + static bool INumberBase.IsCanonical(byte value) => true; + + /// + static bool INumberBase.IsComplexNumber(byte value) => false; + + /// + public static bool IsEvenInteger(byte value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(byte value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(byte value) => false; + + /// + static bool INumberBase.IsInfinity(byte value) => false; + + /// + static bool INumberBase.IsInteger(byte value) => true; + + /// + static bool INumberBase.IsNaN(byte value) => false; + + /// + static bool INumberBase.IsNegative(byte value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(byte value) => false; + + /// + static bool INumberBase.IsNormal(byte value) => value != 0; + + /// + public static bool IsOddInteger(byte value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(byte value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(byte value) => false; + + /// + static bool INumberBase.IsRealNumber(byte value) => true; + + /// + static bool INumberBase.IsSubnormal(byte value) => false; + + /// + static bool INumberBase.IsZero(byte value) => (value == 0); + + /// + static byte INumberBase.MaxMagnitude(byte x, byte y) => Max(x, y); + + /// + static byte INumberBase.MaxMagnitudeNumber(byte x, byte y) => Max(x, y); + + /// + static byte INumberBase.MinMagnitude(byte x, byte y) => Min(x, y); + + /// + static byte INumberBase.MinMagnitudeNumber(byte x, byte y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out byte result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return checked((byte)(char)(object)value); + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(char)) + { + char actualValue = (char)(object)value; + result = checked((byte)actualValue); + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((byte)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((byte)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((byte)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((byte)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((byte)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((byte)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((byte)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((byte)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((byte)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return checked((byte)(ushort)(object)value); + ushort actualValue = (ushort)(object)value; + result = checked((byte)actualValue); + return true; } else if (typeof(TOther) == typeof(uint)) { - return checked((byte)(uint)(object)value); + uint actualValue = (uint)(object)value; + result = checked((byte)actualValue); + return true; } else if (typeof(TOther) == typeof(ulong)) { - return checked((byte)(ulong)(object)value); + ulong actualValue = (ulong)(object)value; + result = checked((byte)actualValue); + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = checked((byte)actualValue); + return true; } else if (typeof(TOther) == typeof(nuint)) { - return checked((byte)(nuint)(object)value); + nuint actualValue = (nuint)(object)value; + result = checked((byte)actualValue); + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out byte result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - var actualValue = (char)(object)value; - return (actualValue > MaxValue) ? MaxValue : (byte)actualValue; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(char)) + { + char actualValue = (char)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + ushort actualValue = (ushort)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(uint)) { - var actualValue = (short)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + uint actualValue = (uint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (int)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + ulong actualValue = (ulong)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + nuint actualValue = (nuint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (byte)actualValue; + return true; } - else if (typeof(TOther) == typeof(sbyte)) + else { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (byte)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(float)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out byte result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(char)) + { + char actualValue = (char)(object)value; + result = (byte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (byte)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (byte)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (ushort)(object)value; - return (actualValue > MaxValue) ? MaxValue : (byte)actualValue; + ushort actualValue = (ushort)(object)value; + result = (byte)actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (byte)actualValue; + uint actualValue = (uint)(object)value; + result = (byte)actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (byte)actualValue; + ulong actualValue = (ulong)(object)value; + result = (byte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (byte)actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (byte)actualValue; + nuint actualValue = (nuint)(object)value; + result = (byte)actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(byte value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (byte)(char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (byte)(decimal)(object)value; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (byte)(double)(object)value; + Half actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (byte)(short)(object)value; + short actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (byte)(int)(object)value; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (byte)(long)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (byte)(nint)(object)value; + nint actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (byte)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (byte)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (byte)(ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) - { - return (byte)(uint)(object)value; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(byte value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (byte)(ulong)(object)value; + Half actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (byte)(nuint)(object)value; + short actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(byte value) => true; - - /// - static bool INumberBase.IsComplexNumber(byte value) => false; - - /// - public static bool IsEvenInteger(byte value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(byte value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(byte value) => false; - - /// - static bool INumberBase.IsInfinity(byte value) => false; - - /// - static bool INumberBase.IsInteger(byte value) => true; - - /// - static bool INumberBase.IsNaN(byte value) => false; - - /// - static bool INumberBase.IsNegative(byte value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(byte value) => false; - - /// - static bool INumberBase.IsNormal(byte value) => value != 0; - - /// - public static bool IsOddInteger(byte value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(byte value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(byte value) => false; - - /// - static bool INumberBase.IsRealNumber(byte value) => true; - - /// - static bool INumberBase.IsSubnormal(byte value) => false; - - /// - static bool INumberBase.IsZero(byte value) => (value == 0); - - /// - static byte INumberBase.MaxMagnitude(byte x, byte y) => Max(x, y); - - /// - static byte INumberBase.MaxMagnitudeNumber(byte x, byte y) => Max(x, y); - - /// - static byte INumberBase.MinMagnitude(byte x, byte y) => Min(x, y); - - /// - static byte INumberBase.MinMagnitudeNumber(byte x, byte y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out byte result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (byte)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (char)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (byte)actualValue; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } + result = default!; + return false; + } + } - result = (byte)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(byte value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `byte` will handle the other unsigned types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + Half actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + short actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (byte)actualValue; + int actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (byte)actualValue; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (ushort)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (byte)actualValue; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (byte)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (ulong)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (byte)actualValue; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (nuint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (byte)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Char.cs b/src/libraries/System.Private.CoreLib/src/System/Char.cs index fd3b1280859e0f..fa100bbb36e381 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Char.cs @@ -1382,476 +1382,490 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static char INumberBase.Abs(char value) => value; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase.CreateChecked(TOther value) + /// + static bool INumberBase.IsCanonical(char value) => true; + + /// + static bool INumberBase.IsComplexNumber(char value) => false; + + /// + static bool INumberBase.IsEvenInteger(char value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(char value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(char value) => false; + + /// + static bool INumberBase.IsInfinity(char value) => false; + + /// + static bool INumberBase.IsInteger(char value) => true; + + /// + static bool INumberBase.IsNaN(char value) => false; + + /// + static bool INumberBase.IsNegative(char value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(char value) => false; + + /// + static bool INumberBase.IsNormal(char value) => value != 0; + + /// + static bool INumberBase.IsOddInteger(char value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(char value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(char value) => false; + + /// + static bool INumberBase.IsRealNumber(char value) => true; + + /// + static bool INumberBase.IsSubnormal(char value) => false; + + /// + static bool INumberBase.IsZero(char value) => (value == 0); + + /// + static char INumberBase.MaxMagnitude(char x, char y) => (char)Math.Max(x, y); + + /// + static char INumberBase.MaxMagnitudeNumber(char x, char y) => (char)Math.Max(x, y); + + /// + static char INumberBase.MinMagnitude(char x, char y) => (char)Math.Min(x, y); + + /// + static char INumberBase.MinMagnitudeNumber(char x, char y) => (char)Math.Min(x, y); + + static char INumberBase.Parse(string s, NumberStyles style, IFormatProvider? provider) => Parse(s); + + static char INumberBase.Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) { - if (typeof(TOther) == typeof(byte)) + if (s.Length != 1) { - return (char)(byte)(object)value; + throw new FormatException(SR.Format_NeedSingleChar); } - else if (typeof(TOther) == typeof(char)) + return s[0]; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out char result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - return (char)(object)value; + byte actualValue = (byte)(object)value; + result = (char)actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((char)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((char)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((char)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((char)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((char)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((char)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((char)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((char)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((char)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (char)(ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = (char)actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return checked((char)(uint)(object)value); + uint actualValue = (uint)(object)value; + result = checked((char)actualValue); + return true; } else if (typeof(TOther) == typeof(ulong)) { - return checked((char)(ulong)(object)value); + ulong actualValue = (ulong)(object)value; + result = checked((char)actualValue); + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = checked((char)actualValue); + return true; } else if (typeof(TOther) == typeof(nuint)) { - return checked((char)(nuint)(object)value); + nuint actualValue = (nuint)(object)value; + result = checked((char)actualValue); + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase.CreateSaturating(TOther value) + static bool INumberBase.TryConvertFromSaturating(TOther value, out char result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (char)(byte)(object)value; + byte actualValue = (byte)(object)value; + result = (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(decimal)) { - return (char)(object)value; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + ushort actualValue = (ushort)(object)value; + result = (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(uint)) { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + uint actualValue = (uint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (short)(object)value; - return (actualValue < MinValue) ? MinValue : (char)actualValue; + ulong actualValue = (ulong)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (int)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + nuint actualValue = (nuint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(sbyte)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out char result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (sbyte)(object)value; - return (actualValue < MinValue) ? MinValue : (char)actualValue; + byte actualValue = (byte)(object)value; + result = (char)actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (char)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (char)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (char)(ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = (char)actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (char)actualValue; + uint actualValue = (uint)(object)value; + result = (char)actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (char)actualValue; + ulong actualValue = (ulong)(object)value; + result = (char)actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (char)actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (char)actualValue; + nuint actualValue = (nuint)(object)value; + result = (char)actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase.CreateTruncating(TOther value) + static bool INumberBase.TryConvertToChecked(char value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (char)(byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) { - return (char)(decimal)(object)value; + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (char)(double)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (char)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (char)(int)(object)value; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (char)(long)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (char)(nint)(object)value; + nint actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (char)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (char)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (char)(ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(char value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) { - return (char)(uint)(object)value; + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (char)(ulong)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (char)(nuint)(object)value; + short actualResult = (value >= short.MaxValue) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(char value) => true; - - /// - static bool INumberBase.IsComplexNumber(char value) => false; - - /// - static bool INumberBase.IsEvenInteger(char value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(char value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(char value) => false; - - /// - static bool INumberBase.IsInfinity(char value) => false; - - /// - static bool INumberBase.IsInteger(char value) => true; - - /// - static bool INumberBase.IsNaN(char value) => false; - - /// - static bool INumberBase.IsNegative(char value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(char value) => false; - - /// - static bool INumberBase.IsNormal(char value) => value != 0; - - /// - static bool INumberBase.IsOddInteger(char value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(char value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(char value) => false; - - /// - static bool INumberBase.IsRealNumber(char value) => true; - - /// - static bool INumberBase.IsSubnormal(char value) => false; - - /// - static bool INumberBase.IsZero(char value) => (value == 0); - - /// - static char INumberBase.MaxMagnitude(char x, char y) => (char)Math.Max(x, y); - - /// - static char INumberBase.MaxMagnitudeNumber(char x, char y) => (char)Math.Max(x, y); - - /// - static char INumberBase.MinMagnitude(char x, char y) => (char)Math.Min(x, y); - - /// - static char INumberBase.MinMagnitudeNumber(char x, char y) => (char)Math.Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static bool INumberBase.TryCreate(TOther value, out char result) - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (char)(byte)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - result = (char)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (char)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (char)actualValue; + sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (char)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; + result = default!; + return false; + } + } - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(char value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `char` will handle the other unsigned types and + // `ConvertTo` will handle the unsigned types - result = (char)actualValue; + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (char)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (char)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (char)actualValue; + int actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (char)actualValue; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (ushort)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (char)actualValue; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (char)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (ulong)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (char)actualValue; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (nuint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (char)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } - static char INumberBase.Parse(string s, NumberStyles style, IFormatProvider? provider) => Parse(s); - - static char INumberBase.Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) - { - if (s.Length != 1) - { - throw new FormatException(SR.Format_NeedSingleChar); - } - return s[0]; - } - static bool INumberBase.TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out char result) => TryParse(s, out result); static bool INumberBase.TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out char result) diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs index 1fea9eba514a5c..fdad839460d8fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs @@ -1344,250 +1344,6 @@ public static decimal Abs(decimal value) return new decimal(in value, value._flags & ~SignMask); } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (decimal)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - return (decimal)(Int128)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (decimal)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - return (decimal)(UInt128)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (decimal)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - var actualValue = (Int128)(object)value; - return (actualValue > new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? MaxValue : - (actualValue < new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)) ? MinValue : (decimal)actualValue; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (decimal)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - var actualValue = (UInt128)(object)value; - return (actualValue > new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? MaxValue : (decimal)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (decimal)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - var actualValue = (Int128)(object)value; - - if (Int128.IsNegative(actualValue)) - { - actualValue = (-actualValue) & new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF); - return -(decimal)actualValue; - } - else - { - actualValue &= new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF); - return (decimal)actualValue; - } - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (decimal)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - var actualValue = (UInt128)(object)value; - actualValue &= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF); - return (decimal)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// public static bool IsCanonical(decimal value) { @@ -1711,111 +1467,305 @@ public static decimal MinMagnitude(decimal x, decimal y) /// static decimal INumberBase.MinMagnitudeNumber(decimal x, decimal y) => MinMagnitude(x, y); - /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out decimal result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `decimal` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) + { + byte actualValue = (byte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualValue = (char)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualValue = (uint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = checked((decimal)actualValue); + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; + } + else + { + result = default; + return false; + } + } + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out decimal result) + static bool INumberBase.TryConvertFromSaturating(TOther value, out decimal result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out decimal result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out decimal result) where TOther : INumberBase { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `decimal` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - result = (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(char)) { - result = (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(ushort)) { - result = (decimal)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(uint)) { - result = (decimal)(double)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? MaxValue : (decimal)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; + } + else + { + result = default; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(decimal value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `decimal` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = checked((double)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = checked((Half)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(short)) { - result = (short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(int)) { - result = (int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(long)) { - result = (long)(object)value; + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (Int128)(object)value; - - if ((actualValue > new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) || (actualValue < new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001))) - { - result = default; - return false; - } - - result = (decimal)actualValue; + Int128 actualResult = checked((Int128)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nint)) { - result = (nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(float)) { - result = (decimal)(float)(object)value; + float actualResult = checked((float)value); + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - result = (ushort)(object)value; + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(decimal value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(decimal value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + private static bool TryConvertTo(decimal value, [NotNullWhen(true)] out TOther result) + where TOther : INumberBase + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `decimal` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = (double)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(Half)) { - result = (uint)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(short)) { - result = (ulong)(object)value; + short actualResult = (value >= short.MaxValue) ? short.MaxValue : + (value <= short.MinValue) ? short.MinValue : (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(UInt128)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (UInt128)(object)value; - - if (actualValue > new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) - { - result = default; - return false; - } - - result = (decimal)actualValue; + int actualResult = (value >= int.MaxValue) ? int.MaxValue : + (value <= int.MinValue) ? int.MinValue : (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(long)) + { + long actualResult = (value >= long.MaxValue) ? long.MaxValue : + (value <= long.MinValue) ? long.MinValue : (long)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = (Int128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) { - result = (nuint)(object)value; + nint actualResult = (value >= nint.MaxValue) ? nint.MaxValue : + (value <= nint.MinValue) ? nint.MinValue : (nint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue : + (value <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index a84a966f9c53f9..1655435fbeae4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -1003,98 +1003,6 @@ public static double MinNumber(double x, double y) /// public static double Abs(double value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateChecked(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (double)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - return (double)(Int128)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - return (double)(UInt128)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateTruncating(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - /// static bool INumberBase.IsCanonical(double value) => true; @@ -1186,13 +1094,258 @@ public static double MinMagnitudeNumber(double x, double y) return y; } - /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out double result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out double result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out double result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out double result) + where TOther : INumberBase + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `double` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (double)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (double)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = actualValue; + return true; + } + else + { + result = default; + return false; + } + } + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out double result) + static bool INumberBase.TryConvertToChecked(double value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `double` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(double value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(double value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + private static bool TryConvertTo(double value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase { - result = CreateSaturating(value); - return true; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `double` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value >= +79228162514264337593543950336.0) ? decimal.MaxValue : + (value <= -79228162514264337593543950336.0) ? decimal.MinValue : + IsNaN(value) ? 0.0m : (decimal)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value >= ulong.MaxValue) ? ulong.MaxValue : + (value <= ulong.MinValue) ? ulong.MinValue : + IsNaN(value) ? 0 : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value >= 340282366920938463463374607431768211455.0) ? UInt128.MaxValue : + (value <= 0.0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { +#if TARGET_64BIT + nuint actualResult = (value >= ulong.MaxValue) ? unchecked((nuint)ulong.MaxValue) : + (value <= ulong.MinValue) ? unchecked((nuint)ulong.MinValue) : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#else + nuint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#endif + } + else + { + result = default!; + return false; + } } // diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 782abe963f7a37..059299f5effb5e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -539,64 +539,311 @@ public bool TryFormat(Span destination, out int charsWritten, [StringSynta return Number.TryFormatHalf(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); } - // -----------------------Start of to-half conversions------------------------- + // + // Explicit Convert To Half + // - public static explicit operator Half(float value) + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(char value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(decimal value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(double value) { - const int SingleMaxExponent = 0xFF; + const int DoubleMaxExponent = 0x7FF; - uint floatInt = BitConverter.SingleToUInt32Bits(value); - bool sign = (floatInt & float.SignMask) >> float.SignShift != 0; - int exp = (int)(floatInt & float.BiasedExponentMask) >> float.BiasedExponentShift; - uint sig = floatInt & float.TrailingSignificandMask; + ulong doubleInt = BitConverter.DoubleToUInt64Bits(value); + bool sign = (doubleInt & double.SignMask) >> double.SignShift != 0; + int exp = (int)((doubleInt & double.BiasedExponentMask) >> double.BiasedExponentShift); + ulong sig = doubleInt & double.TrailingSignificandMask; - if (exp == SingleMaxExponent) + if (exp == DoubleMaxExponent) { if (sig != 0) // NaN { - return CreateHalfNaN(sign, (ulong)sig << 41); // Shift the significand bits to the left end + return CreateHalfNaN(sign, sig << 12); // Shift the significand bits to the left end } return sign ? NegativeInfinity : PositiveInfinity; } - uint sigHalf = sig >> 9 | ((sig & 0x1FFU) != 0 ? 1U : 0U); // RightShiftJam - + uint sigHalf = (uint)ShiftRightJam(sig, 38); if ((exp | (int)sigHalf) == 0) { return new Half(sign, 0, 0); } - - return new Half(RoundPackToHalf(sign, (short)(exp - 0x71), (ushort)(sigHalf | 0x4000))); + return new Half(RoundPackToHalf(sign, (short)(exp - 0x3F1), (ushort)(sigHalf | 0x4000))); } - public static explicit operator Half(double value) + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(short value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(int value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(long value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(nint value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static explicit operator Half(float value) { - const int DoubleMaxExponent = 0x7FF; + const int SingleMaxExponent = 0xFF; - ulong doubleInt = BitConverter.DoubleToUInt64Bits(value); - bool sign = (doubleInt & double.SignMask) >> double.SignShift != 0; - int exp = (int)((doubleInt & double.BiasedExponentMask) >> double.BiasedExponentShift); - ulong sig = doubleInt & double.TrailingSignificandMask; + uint floatInt = BitConverter.SingleToUInt32Bits(value); + bool sign = (floatInt & float.SignMask) >> float.SignShift != 0; + int exp = (int)(floatInt & float.BiasedExponentMask) >> float.BiasedExponentShift; + uint sig = floatInt & float.TrailingSignificandMask; - if (exp == DoubleMaxExponent) + if (exp == SingleMaxExponent) { if (sig != 0) // NaN { - return CreateHalfNaN(sign, sig << 12); // Shift the significand bits to the left end + return CreateHalfNaN(sign, (ulong)sig << 41); // Shift the significand bits to the left end } return sign ? NegativeInfinity : PositiveInfinity; } - uint sigHalf = (uint)ShiftRightJam(sig, 38); + uint sigHalf = sig >> 9 | ((sig & 0x1FFU) != 0 ? 1U : 0U); // RightShiftJam + if ((exp | (int)sigHalf) == 0) { return new Half(sign, 0, 0); } - return new Half(RoundPackToHalf(sign, (short)(exp - 0x3F1), (ushort)(sigHalf | 0x4000))); + + return new Half(RoundPackToHalf(sign, (short)(exp - 0x71), (ushort)(sigHalf | 0x4000))); } - // -----------------------Start of from-half conversions------------------------- - public static explicit operator float(Half value) + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + [CLSCompliant(false)] + public static explicit operator Half(ushort value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + [CLSCompliant(false)] + public static explicit operator Half(uint value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + [CLSCompliant(false)] + public static explicit operator Half(ulong value) => (Half)(float)value; + + /// Explicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + [CLSCompliant(false)] + public static explicit operator Half(nuint value) => (Half)(float)value; + + // + // Explicit Convert From Half + // + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator byte(Half value) => (byte)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked byte(Half value) => checked((byte)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator char(Half value) => (char)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked char(Half value) => checked((char)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator decimal(Half value) => (decimal)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator short(Half value) => (short)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked short(Half value) => checked((short)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator int(Half value) => (int)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked int(Half value) => checked((int)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator long(Half value) => (long)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked long(Half value) => checked((long)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable . + /// The value to convert. + /// converted to a 128-bit signed integer. + public static explicit operator Int128(Half value) => (Int128)(double)(value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable , throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to a 128-bit signed integer. + /// is not representable by . + public static explicit operator checked Int128(Half value) => checked((Int128)(double)(value)); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator nint(Half value) => (nint)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + public static explicit operator checked nint(Half value) => checked((nint)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [CLSCompliant(false)] + public static explicit operator sbyte(Half value) => (sbyte)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked sbyte(Half value) => checked((sbyte)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [CLSCompliant(false)] + public static explicit operator ushort(Half value) => (ushort)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked ushort(Half value) => checked((ushort)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [CLSCompliant(false)] + public static explicit operator uint(Half value) => (uint)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked uint(Half value) => checked((uint)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [CLSCompliant(false)] + public static explicit operator ulong(Half value) => (ulong)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked ulong(Half value) => checked((ulong)(float)value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable . + /// The value to convert. + /// converted to a 128-bit unsigned integer. + [CLSCompliant(false)] + public static explicit operator UInt128(Half value) => (UInt128)(double)(value); + + /// Explicitly converts a half-precision floating-point value to its nearest representable , throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to a 128-bit unsigned integer. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked UInt128(Half value) => checked((UInt128)(double)(value)); + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [CLSCompliant(false)] + public static explicit operator nuint(Half value) => (nuint)(float)value; + + /// Explicitly converts a half-precision floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [CLSCompliant(false)] + public static explicit operator checked nuint(Half value) => checked((nuint)(float)value); + + // + // Implicit Convert To Half + // + + /// Implicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + public static implicit operator Half(byte value) => (Half)(float)value; + + /// Implicitly converts a value to its nearest representable half-precision floating-point value. + /// The value to convert. + /// converted to its nearest representable half-precision floating-point value. + [CLSCompliant(false)] + public static implicit operator Half(sbyte value) => (Half)(float)value; + + // + // Implicit Convert From Half (actually explicit due to back-compat) + // + + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator double(Half value) { bool sign = IsNegative(value); int exp = value.BiasedExponent; @@ -606,25 +853,28 @@ public static explicit operator float(Half value) { if (sig != 0) { - return CreateSingleNaN(sign, (ulong)sig << 54); + return CreateDoubleNaN(sign, (ulong)sig << 54); } - return sign ? float.NegativeInfinity : float.PositiveInfinity; + return sign ? double.NegativeInfinity : double.PositiveInfinity; } if (exp == 0) { if (sig == 0) { - return BitConverter.UInt32BitsToSingle(sign ? float.SignMask : 0); // Positive / Negative zero + return BitConverter.UInt64BitsToDouble(sign ? double.SignMask : 0); // Positive / Negative zero } (exp, sig) = NormSubnormalF16Sig(sig); exp -= 1; } - return CreateSingle(sign, (byte)(exp + 0x70), sig << 13); + return CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42); } - public static explicit operator double(Half value) + /// Explicitly converts a half-precision floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + public static explicit operator float(Half value) { bool sign = IsNegative(value); int exp = value.BiasedExponent; @@ -634,22 +884,22 @@ public static explicit operator double(Half value) { if (sig != 0) { - return CreateDoubleNaN(sign, (ulong)sig << 54); + return CreateSingleNaN(sign, (ulong)sig << 54); } - return sign ? double.NegativeInfinity : double.PositiveInfinity; + return sign ? float.NegativeInfinity : float.PositiveInfinity; } if (exp == 0) { if (sig == 0) { - return BitConverter.UInt64BitsToDouble(sign ? double.SignMask : 0); // Positive / Negative zero + return BitConverter.UInt32BitsToSingle(sign ? float.SignMask : 0); // Positive / Negative zero } (exp, sig) = NormSubnormalF16Sig(sig); exp -= 1; } - return CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42); + return CreateSingle(sign, (byte)(exp + 0x70), sig << 13); } // IEEE 754 specifies NaNs to be propagated @@ -770,7 +1020,7 @@ public static bool IsPow2(Half value) byte biasedExponent = ExtractBiasedExponentFromBits(bits); ushort trailingSignificand = ExtractTrailingSignificandFromBits(bits); - return (value > default(Half)) + return (value > Zero) && (biasedExponent != MinBiasedExponent) && (biasedExponent != MaxBiasedExponent) && (trailingSignificand == MinTrailingSignificand); } @@ -1195,98 +1445,6 @@ public static Half MinNumber(Half x, Half y) /// public static Half Abs(Half value) => (Half)MathF.Abs((float)value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateChecked(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (Half)(byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (Half)(char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Half)(float)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (Half)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (Half)(short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (Half)(int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (Half)(long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - return (Half)(Int128)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (Half)(long)(nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (Half)(sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (Half)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (Half)(ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (Half)(uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (Half)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - return (Half)(UInt128)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (Half)(ulong)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateTruncating(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - /// static bool INumberBase.IsCanonical(Half value) => true; @@ -1378,13 +1536,251 @@ public static Half MinMagnitudeNumber(Half x, Half y) return y; } - /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out Half result) + { + return TryConvertFrom(value, out result); + } + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out Half result) + static bool INumberBase.TryConvertFromSaturating(TOther value, out Half result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out Half result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out Half result) where TOther : INumberBase { - result = CreateSaturating(value); - return true; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Half` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = (Half)actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (Half)actualValue; + return true; + } + else + { + result = default; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(Half value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Half` will handle the other signed types and + // `ConvertTo` will handle the unsigned types. + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(Half value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(Half value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + private static bool TryConvertTo(Half value, [NotNullWhen(true)] out TOther result) + where TOther : INumberBase + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Half` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + var actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value == PositiveInfinity) ? char.MaxValue : + (value <= Zero) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value == PositiveInfinity) ? decimal.MaxValue : + (value == NegativeInfinity) ? decimal.MinValue : + IsNaN(value) ? 0.0m : (decimal)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value == PositiveInfinity) ? ushort.MaxValue : + (value <= Zero) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value == PositiveInfinity) ? uint.MaxValue : + (value <= Zero) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value == PositiveInfinity) ? ulong.MaxValue : + (value <= Zero) ? ulong.MinValue : + IsNaN(value) ? 0 : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value == PositiveInfinity) ? UInt128.MaxValue : + (value <= Zero) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (value == PositiveInfinity) ? nuint.MaxValue : + (value <= Zero) ? nuint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } } // diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs index 56919478ccca7d..31fdfd22ebf813 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs @@ -604,17 +604,6 @@ internal static Int128 ToInt128(double value) } } - /// Explicitly converts a value to a 128-bit signed integer. - /// The value to convert. - /// converted to a 128-bit signed integer. - public static explicit operator Int128(Half value) => (Int128)(double)(value); - - /// Explicitly converts a value to a 128-bit signed integer, throwing an overflow exception for any values that fall outside the representable range. - /// The value to convert. - /// converted to a 128-bit signed integer. - /// is not representable by . - public static explicit operator checked Int128(Half value) => checked((Int128)(double)(value)); - /// Explicitly converts a value to a 128-bit signed integer. /// The value to convert. /// converted to a 128-bit signed integer. @@ -1286,222 +1275,6 @@ public static Int128 Abs(Int128 value) return value; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return checked((Int128)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((Int128)(double)(object)value); - } - else if (typeof(TOther) == typeof(Half)) - { - return checked((Int128)(Half)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((Int128)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Int128)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (Int128)(double)(object)value; - } - else if (typeof(TOther) == typeof(Half)) - { - return (Int128)(Half)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (Int128)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Int128)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (Int128)(double)(object)value; - } - else if (typeof(TOther) == typeof(Half)) - { - return (Int128)(Half)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (Int128)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(Int128 value) => true; @@ -1639,114 +1412,423 @@ public static Int128 MinMagnitude(Int128 x, Int128 y) /// static Int128 INumberBase.MinMagnitudeNumber(Int128 x, Int128 y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out Int128 result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out Int128 result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) { - result = (byte)(object)value; + double actualValue = (double)(object)value; + result = checked((Int128)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Half)) { - result = (char)(object)value; + Half actualValue = (Half)(object)value; + result = checked((Int128)actualValue); return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) { - result = (Int128)(decimal)(object)value; + int actualValue = (int)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (double)(object)value; + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((Int128)actualValue); + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < -170141183460469231731687303715884105728.0) || (actualValue >= +170141183460469231731687303715884105728.0) || double.IsNaN(actualValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out Int128 result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (Int128)actualValue; + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= +170141183460469231731687303715884105727.0) ? MaxValue : + (actualValue <= -170141183460469231731687303715884105728.0) ? MinValue : (Int128)actualValue; return true; } else if (typeof(TOther) == typeof(Half)) { - var actualValue = (Half)(object)value; + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (Int128)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= +170141183460469231731687303715884105727.0f) ? MaxValue : + (actualValue <= -170141183460469231731687303715884105728.0f) ? MinValue : (Int128)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < Half.MinValue) || (actualValue > Half.MaxValue) || Half.IsNaN(actualValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out Int128 result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (Int128)actualValue; + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= +170141183460469231731687303715884105727.0) ? MaxValue : + (actualValue <= -170141183460469231731687303715884105728.0) ? MinValue : (Int128)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (Int128)actualValue; return true; } else if (typeof(TOther) == typeof(short)) { - result = (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - result = (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - result = (long)(object)value; + long actualValue = (long)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(nint)) { - result = (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= +170141183460469231731687303715884105727.0f) ? MaxValue : + (actualValue <= -170141183460469231731687303715884105728.0f) ? MinValue : (Int128)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < -170141183460469231731687303715884105728.0f) || (actualValue >= +170141183460469231731687303715884105728.0f) || float.IsNaN(actualValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(Int128 value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - result = (Int128)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(Int128 value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value >= new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? decimal.MaxValue : + (value <= new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)) ? decimal.MinValue : (decimal)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - result = (uint)(object)value; + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - result = (ulong)(object)value; + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - result = (nuint)(object)value; + nuint actualResult = (value >= nuint.MaxValue) ? nuint.MaxValue : + (value <= nuint.MinValue) ? nuint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(Int128 value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `Int128` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value >= new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? decimal.MaxValue : + (value <= new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)) ? decimal.MinValue : (decimal)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Int16.cs b/src/libraries/System.Private.CoreLib/src/System/Int16.cs index 0456102d42d950..75025b7a59732e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int16.cs @@ -577,227 +577,6 @@ public static short CopySign(short value, short sign) /// public static short Abs(short value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return checked((short)(char)(object)value); - } - else if (typeof(TOther) == typeof(decimal)) - { - return checked((short)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((short)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return checked((short)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((short)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((short)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((short)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return checked((short)(ushort)(object)value); - } - else if (typeof(TOther) == typeof(uint)) - { - return checked((short)(uint)(object)value); - } - else if (typeof(TOther) == typeof(ulong)) - { - return checked((short)(ulong)(object)value); - } - else if (typeof(TOther) == typeof(nuint)) - { - return checked((short)(nuint)(object)value); - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - var actualValue = (char)(object)value; - return (actualValue > MaxValue) ? MaxValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(decimal)) - { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(double)) - { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - var actualValue = (int)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(long)) - { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(nint)) - { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(ushort)) - { - var actualValue = (ushort)(object)value; - return (actualValue > MaxValue) ? MaxValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(uint)) - { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(ulong)) - { - var actualValue = (ulong)(object)value; - return (actualValue > (uint)MaxValue) ? MaxValue : (short)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - var actualValue = (nuint)(object)value; - return (actualValue > (uint)MaxValue) ? MaxValue : (short)actualValue; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (short)(char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (short)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (short)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (short)(int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (short)(long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (short)(nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (short)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (short)(ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (short)(uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (short)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (short)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(short value) => true; @@ -935,173 +714,421 @@ public static short MinMagnitude(short x, short y) /// static short INumberBase.MinMagnitudeNumber(short x, short y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out short result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out short result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((short)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) { - result = (byte)(object)value; + Half actualValue = (Half)(object)value; + result = checked((short)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (char)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (short)actualValue; + int actualValue = (int)(object)value; + result = checked((short)actualValue); return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (short)actualValue; + long actualValue = (long)(object)value; + result = checked((short)actualValue); return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (double)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + Int128 actualValue = (Int128)(object)value; + result = checked((short)actualValue); + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = checked((short)actualValue); + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((short)actualValue); + return true; + } + else + { + result = default; + return false; + } + } - result = (short)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out short result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(Half)) { - result = (short)(object)value; + Half actualValue = (Half)(object)value; + result = (actualValue >= BitConverter.UInt16BitsToHalf(0x7800)) ? MaxValue : + (actualValue <= BitConverter.UInt16BitsToHalf(0xF800)) ? MinValue : (short)actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - var actualValue = (int)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + int actualValue = (int)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else + { + result = default; + return false; + } + } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out short result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue >= BitConverter.UInt16BitsToHalf(0x7800)) ? MaxValue : + (actualValue <= BitConverter.UInt16BitsToHalf(0xF800)) ? MinValue : (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; result = (short)actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - var actualValue = (long)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + long actualValue = (long)(object)value; + result = (short)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; result = (short)actualValue; return true; } else if (typeof(TOther) == typeof(nint)) { - var actualValue = (nint)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + nint actualValue = (nint)(object)value; result = (short)actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (short)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(short value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (short)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (ushort)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (short)actualValue; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (short)actualValue; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (uint)MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(short value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (short)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value <= 0) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value <= 0) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value <= 0) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; + nuint actualResult = (value <= 0) ? 0 : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (uint)MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(short value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `short` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (short)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Int32.cs b/src/libraries/System.Private.CoreLib/src/System/Int32.cs index 291030805a1897..b40fedc2636b50 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int32.cs @@ -569,223 +569,6 @@ public static int CopySign(int value, int sign) /// public static int Abs(int value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return checked((int)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((int)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return checked((int)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((int)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((int)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return checked((int)(ushort)(object)value); - } - else if (typeof(TOther) == typeof(uint)) - { - return checked((int)(uint)(object)value); - } - else if (typeof(TOther) == typeof(ulong)) - { - return checked((int)(ulong)(object)value); - } - else if (typeof(TOther) == typeof(nuint)) - { - return checked((int)(nuint)(object)value); - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(double)) - { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(nint)) - { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(ulong)) - { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (int)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (int)actualValue; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (int)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (int)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (int)(long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (int)(nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (int)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (int)(uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (int)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (int)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(int value) => true; @@ -923,149 +706,422 @@ public static int MinMagnitude(int x, int y) /// static int INumberBase.MinMagnitudeNumber(int x, int y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out int result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out int result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((int)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) { - result = (byte)(object)value; + Half actualValue = (Half)(object)value; + result = checked((int)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(short)) { - result = (char)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (int)actualValue; + long actualValue = (long)(object)value; + result = checked((int)actualValue); return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (double)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + Int128 actualValue = (Int128)(object)value; + result = checked((int)actualValue); + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = checked((int)actualValue); + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((int)actualValue); + return true; + } + else + { + result = default; + return false; + } + } - result = (int)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out int result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(Half)) { - result = (short)(object)value; + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (int)actualValue; return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(short)) { - result = (int)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - var actualValue = (long)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + long actualValue = (long)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else + { + result = default; + return false; + } + } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out int result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = (int)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; result = (int)actualValue; return true; } else if (typeof(TOther) == typeof(nint)) { - var actualValue = (nint)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + nint actualValue = (nint)(object)value; result = (int)actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (int)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(int value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (int)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (int)actualValue; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(int value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (int)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value <= 0) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; + nuint actualResult = (value <= 0) ? 0 : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(int value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `int` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (int)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Int64.cs b/src/libraries/System.Private.CoreLib/src/System/Int64.cs index 34b2add14624a5..0c7fa4a26d3f30 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int64.cs @@ -556,218 +556,6 @@ public static long CopySign(long value, long sign) /// public static long Abs(long value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return checked((long)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((long)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((long)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return checked((long)(ulong)(object)value); - } - else if (typeof(TOther) == typeof(nuint)) - { - return checked((long)(nuint)(object)value); - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (long)actualValue; - } - else if (typeof(TOther) == typeof(double)) - { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (long)actualValue; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (long)actualValue; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (long)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (long)actualValue; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (long)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (long)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (long)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (long)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (long)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(long value) => true; @@ -905,125 +693,428 @@ public static long MinMagnitude(long x, long y) /// static long INumberBase.MinMagnitudeNumber(long x, long y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out long result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out long result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((long)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) { - result = (byte)(object)value; + Half actualValue = (Half)(object)value; + result = checked((long)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(short)) { - result = (char)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (long)actualValue; + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = checked((long)actualValue); + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((long)actualValue); + return true; + } + else { - var actualValue = (double)(object)value; + result = default; + return false; + } + } - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out long result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (long)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (long)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (long)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (long)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - result = (long)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out long result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (long)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? MaxValue : + (actualValue == Half.NegativeInfinity) ? MinValue : (long)actualValue; return true; } else if (typeof(TOther) == typeof(short)) { - result = (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - result = (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Int128)) { - result = (long)(object)value; + Int128 actualValue = (Int128)(object)value; + result = (long)actualValue; return true; } else if (typeof(TOther) == typeof(nint)) { - result = (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (long)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(long value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (long)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - result = (uint)(object)value; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(long value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (long)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; +#if TARGET_32BIT + nuint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#else + nuint actualResult = (value <= 0) ? 0 : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#endif + } + else + { + result = default!; + return false; + } + } - if (actualValue > MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(long value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `long` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (long)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs index 36de25a6061954..9d3e923096b907 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs @@ -529,221 +529,6 @@ public static nint CopySign(nint value, nint sign) /// public static nint Abs(nint value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((nint)(nint)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((nint)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return checked((nint)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((nint)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return checked((nint)(uint)(object)value); - } - else if (typeof(TOther) == typeof(ulong)) - { - return checked((nint)(ulong)(object)value); - } - else if (typeof(TOther) == typeof(nuint)) - { - return checked((nint)(nuint)(object)value); - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - var actualValue = (nint)(object)value; - return (actualValue > nint.MaxValue) ? MaxValue : - (actualValue < nint.MinValue) ? MinValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(double)) - { - var actualValue = (double)(object)value; - return (actualValue > nint.MaxValue) ? MaxValue : - (actualValue < nint.MinValue) ? MinValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - var actualValue = (long)(object)value; - return (actualValue > nint.MaxValue) ? MaxValue : - (actualValue < nint.MinValue) ? MinValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - var actualValue = (float)(object)value; - return (actualValue > nint.MaxValue) ? MaxValue : - (actualValue < nint.MinValue) ? MinValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - var actualValue = (uint)(object)value; - return (actualValue > nint.MaxValue) ? MaxValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(ulong)) - { - var actualValue = (ulong)(object)value; - return (actualValue > (nuint)nint.MaxValue) ? MaxValue : (nint)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - var actualValue = (nuint)(object)value; - return (actualValue > (nuint)nint.MaxValue) ? MaxValue : (nint)actualValue; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(nint)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (nint)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (nint)(long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (nint)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (nint)(uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (nint)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nint)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(nint value) => true; @@ -881,141 +666,422 @@ public static nint MinMagnitude(nint x, nint y) /// static nint INumberBase.MinMagnitudeNumber(nint x, nint y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out nint result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out nint result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((nint)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) { - result = (byte)(object)value; + Half actualValue = (Half)(object)value; + result = checked((nint)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(short)) { - result = (char)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (nint)(object)value; - - if ((actualValue < nint.MinValue) || (actualValue > nint.MaxValue)) - { - result = default; - return false; - } - - result = (nint)actualValue; + int actualValue = (int)(object)value; + result = actualValue; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (double)(object)value; - - if ((actualValue < nint.MinValue) || (actualValue > nint.MaxValue)) - { - result = default; - return false; - } + long actualValue = (long)(object)value; + result = checked((nint)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = checked((nint)actualValue); + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((nint)actualValue); + return true; + } + else + { + result = default; + return false; + } + } - result = (nint)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out nint result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? unchecked((nint)nint_t.MaxValue) : + (actualValue == Half.NegativeInfinity) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; return true; } else if (typeof(TOther) == typeof(short)) { - result = (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - result = (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - var actualValue = (long)(object)value; - - if ((actualValue < nint.MinValue) || (actualValue > nint.MaxValue)) - { - result = default; - return false; - } + long actualValue = (long)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else + { + result = default; + return false; + } + } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out nint result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue == Half.PositiveInfinity) ? unchecked((nint)nint_t.MaxValue) : + (actualValue == Half.NegativeInfinity) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; result = (nint)actualValue; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(Int128)) { - result = (nint)(object)value; + Int128 actualValue = (Int128)(object)value; + result = (nint)actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= nint_t.MaxValue) ? unchecked((nint)nint_t.MaxValue) : + (actualValue <= nint_t.MinValue) ? unchecked((nint)nint_t.MinValue) : (nint)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < nint.MinValue) || (actualValue > nint.MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(nint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (nint)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - - if (actualValue > nint.MaxValue) - { - result = default; - return false; - } - - result = (nint)actualValue; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (nuint)nint.MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(nint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (nint)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; + nuint actualResult = (value <= 0) ? 0 : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (nuint)nint.MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(nint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nint` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (nint)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs index d0aef03aa3952c..17ec3897a4f422 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs @@ -1152,7 +1152,7 @@ internal static ParsingStatus TryParseInt128IntegerStyle(ReadOnlySpan valu // Potential overflow now processing the 39th digit. overflow = answer > new Int128(0x0CCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC); // Int128.MaxValue / 10 answer = answer * 10 + num - '0'; - overflow |= (UInt128)answer > (UInt128)Int128.MaxValue + (((uint)sign) >> 31); + overflow |= (UInt128)answer > new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF) + (((uint)sign) >> 31); if ((uint)index >= (uint)value.Length) goto DoneAtEndButPotentialOverflow; @@ -2548,7 +2548,7 @@ internal static unsafe bool TryParseHalf(ReadOnlySpan value, NumberStyles } else { - result = (Half)0; + result = Half.Zero; return false; } } @@ -2565,7 +2565,7 @@ internal static unsafe bool TryParseHalf(ReadOnlySpan value, NumberStyles } else { - result = (Half)0; + result = Half.Zero; return false; // We really failed } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs index c38edf1ca3b169..cefd019a9aa245 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Runtime.CompilerServices; namespace System.Numerics { @@ -45,24 +46,69 @@ public interface INumberBase /// An instance of created from . /// is not supported. /// is not representable by . - static abstract TSelf CreateChecked(TOther value) - where TOther : INumberBase; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateChecked(TOther value) + where TOther : INumberBase + { + TSelf? result; + + if (typeof(TOther) == typeof(TSelf)) + { + result = (TSelf)(object)value; + } + else if (!TSelf.TryConvertFromChecked(value, out result) && !TOther.TryConvertToChecked(value, out result)) + { + ThrowHelper.ThrowNotSupportedException(); + } + + return result; + } /// Creates an instance of the current type from a value, saturating any values that fall outside the representable range of the current type. /// The type of . /// The value which is used to create the instance of . /// An instance of created from , saturating if falls outside the representable range of . /// is not supported. - static abstract TSelf CreateSaturating(TOther value) - where TOther : INumberBase; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateSaturating(TOther value) + where TOther : INumberBase + { + TSelf? result; + + if (typeof(TOther) == typeof(TSelf)) + { + result = (TSelf)(object)value; + } + else if (!TSelf.TryConvertFromSaturating(value, out result) && !TOther.TryConvertToSaturating(value, out result)) + { + ThrowHelper.ThrowNotSupportedException(); + } + + return result; + } /// Creates an instance of the current type from a value, truncating any values that fall outside the representable range of the current type. /// The type of . /// The value which is used to create the instance of . /// An instance of created from , truncating if falls outside the representable range of . /// is not supported. - static abstract TSelf CreateTruncating(TOther value) - where TOther : INumberBase; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateTruncating(TOther value) + where TOther : INumberBase + { + TSelf? result; + + if (typeof(TOther) == typeof(TSelf)) + { + result = (TSelf)(object)value; + } + else if (!TSelf.TryConvertFromTruncating(value, out result) && !TOther.TryConvertToTruncating(value, out result)) + { + ThrowHelper.ThrowNotSupportedException(); + } + + return result; + } /// Determines if a value is in its canonical representation. /// The value to be checked. @@ -215,13 +261,54 @@ static abstract TSelf CreateTruncating(TOther value) /// is not representable by . static abstract TSelf Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider); - /// Tries to create an instance of the current type from a value. + /// Tries to convert a value to an instance of the the current type, throwing an overflow exception for any values that fall outside the representable range of the current type. /// The type of . /// The value which is used to create the instance of . - /// On return, contains the result of succesfully creating an instance of from or an undefined value on failure. - /// true if an instance of the current type was succesfully created from ; otherwise, false. - /// is not supported. - static abstract bool TryCreate(TOther value, out TSelf result) + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + /// is not representable by . + protected static abstract bool TryConvertFromChecked(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase; + + /// Tries to convert a value to an instance of the the current type, saturating any values that fall outside the representable range of the current type. + /// The type of . + /// The value which is used to create the instance of . + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + protected static abstract bool TryConvertFromSaturating(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase; + + /// Tries to convert a value to an instance of the the current type, truncating any values that fall outside the representable range of the current type. + /// The type of . + /// The value which is used to create the instance of . + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + protected static abstract bool TryConvertFromTruncating(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase; + + /// Tries to convert an instance of the the current type to another type, throwing an overflow exception for any values that fall outside the representable range of the current type. + /// The type to which should be converted. + /// The value which is used to create the instance of . + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + /// is not representable by . + protected static abstract bool TryConvertToChecked(TSelf value, [NotNullWhen(true)] out TOther? result) + where TOther : INumberBase; + + /// Tries to convert an instance of the the current type to another type, saturating any values that fall outside the representable range of the current type. + /// The type to which should be converted. + /// The value which is used to create the instance of . + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + protected static abstract bool TryConvertToSaturating(TSelf value, [NotNullWhen(true)] out TOther? result) + where TOther : INumberBase; + + /// Tries to convert an instance of the the current type to another type, truncating any values that fall outside the representable range of the current type. + /// The type to which should be converted. + /// The value which is used to create the instance of . + /// On return, contains an instance of converted from . + /// false if is not supported; otherwise, true. + protected static abstract bool TryConvertToTruncating(TSelf value, [NotNullWhen(true)] out TOther? result) where TOther : INumberBase; /// Tries to parses a string into a value. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs index 97f3a349c28683..f197cbc6f962e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -253,42 +253,103 @@ public double Value [NonVersionable] public static explicit operator byte(NFloat value) => (byte)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked byte(NFloat value) => checked((byte)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. [NonVersionable] public static explicit operator char(NFloat value) => (char)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked char(NFloat value) => checked((char)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. [NonVersionable] public static explicit operator decimal(NFloat value) => (decimal)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [NonVersionable] + public static explicit operator Half(NFloat value) => (Half)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. [NonVersionable] public static explicit operator short(NFloat value) => (short)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked short(NFloat value) => checked((short)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. [NonVersionable] public static explicit operator int(NFloat value) => (int)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked int(NFloat value) => checked((int)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. [NonVersionable] public static explicit operator long(NFloat value) => (long)(value._value); - /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. /// The value to convert. - /// converted to its nearest representable value. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked long(NFloat value) => checked((long)(value._value)); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [NonVersionable] + public static explicit operator Int128(NFloat value) => (Int128)(value._value); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked Int128(NFloat value) => checked((Int128)(value._value)); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. [NonVersionable] public static explicit operator nint(NFloat value) => (nint)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + public static explicit operator checked nint(NFloat value) => checked((nint)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. @@ -296,6 +357,14 @@ public double Value [CLSCompliant(false)] public static explicit operator sbyte(NFloat value) => (sbyte)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked sbyte(NFloat value) => checked((sbyte)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. @@ -309,6 +378,14 @@ public double Value [CLSCompliant(false)] public static explicit operator ushort(NFloat value) => (ushort)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked ushort(NFloat value) => checked((ushort)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. @@ -316,6 +393,14 @@ public double Value [CLSCompliant(false)] public static explicit operator uint(NFloat value) => (uint)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked uint(NFloat value) => checked((uint)(value._value)); + /// Explicitly converts a native-sized floating-point value to its nearest representable value. /// The value to convert. /// converted to its nearest representable value. @@ -323,13 +408,44 @@ public double Value [CLSCompliant(false)] public static explicit operator ulong(NFloat value) => (ulong)(value._value); - /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. /// The value to convert. - /// converted to its nearest representable value. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked ulong(NFloat value) => checked((ulong)(value._value)); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator UInt128(NFloat value) => (UInt128)(value._value); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked UInt128(NFloat value) => checked((UInt128)(value._value)); + + /// Explicitly converts a native-sized floating-point value to its nearest representable value. + /// The value to convert. + /// converted to its nearest representable value. [NonVersionable] [CLSCompliant(false)] public static explicit operator nuint(NFloat value) => (nuint)(value._value); + /// Explicitly converts a native-sized floating-point value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range. + /// The value to convert. + /// converted to its nearest representable value. + /// is not representable by . + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked nuint(NFloat value) => checked((nuint)(value._value)); + // // Implicit Convert To NFloat // @@ -346,6 +462,12 @@ public double Value [NonVersionable] public static implicit operator NFloat(char value) => new NFloat((NativeType)value); + /// Implicitly converts a value to its nearest representable native-sized floating-point value. + /// The value to convert. + /// converted to its nearest representable native-sized floating-point value. + [NonVersionable] + public static implicit operator NFloat(Half value) => (NFloat)(float)value; + /// Implicitly converts a value to its nearest representable native-sized floating-point value. /// The value to convert. /// converted to its nearest representable native-sized floating-point value. @@ -364,6 +486,20 @@ public double Value [NonVersionable] public static implicit operator NFloat(long value) => new NFloat((NativeType)value); + /// Explicitly converts a to its nearest representable native-sized floating-point value. + /// The value to convert. + /// converted to its nearest representable native-sized floating-point value. + [NonVersionable] + public static explicit operator NFloat(Int128 value) + { + if (Int128.IsNegative(value)) + { + value = -value; + return -(NFloat)(UInt128)(value); + } + return (NFloat)(UInt128)(value); + } + /// Implicitly converts a value to its nearest representable native-sized floating-point value. /// The value to convert. /// converted to its nearest representable native-sized floating-point value. @@ -404,6 +540,13 @@ public double Value [CLSCompliant(false)] public static implicit operator NFloat(ulong value) => new NFloat((NativeType)value); + /// Explicitly converts to its nearest representable native-sized floating-point value. + /// The value to convert. + /// converted to its nearest representable native-sized floating-point value. + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator NFloat(UInt128 value) => (NFloat)(double)(value); + /// Implicitly converts a value to its nearest representable native-sized floating-point value. /// The value to convert. /// converted to its nearest representable native-sized floating-point value. @@ -1137,140 +1280,438 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// public static NFloat Abs(NFloat value) => new NFloat(NativeType.Abs(value._value)); - /// + /// + static bool INumberBase.IsCanonical(NFloat value) => true; + + /// + static bool INumberBase.IsComplexNumber(NFloat value) => false; + + /// + public static bool IsEvenInteger(NFloat value) => NativeType.IsEvenInteger(value._value); + + /// + static bool INumberBase.IsImaginaryNumber(NFloat value) => false; + + /// + public static bool IsInteger(NFloat value) => NativeType.IsInteger(value._value); + + /// + public static bool IsOddInteger(NFloat value) => NativeType.IsOddInteger(value._value); + + /// + public static bool IsPositive(NFloat value) => NativeType.IsPositive(value._value); + + /// + public static bool IsRealNumber(NFloat value) => NativeType.IsRealNumber(value._value); + + /// + static bool INumberBase.IsZero(NFloat value) => (value == 0); + + /// + public static NFloat MaxMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitude(x._value, y._value)); + + /// + public static NFloat MaxMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitudeNumber(x._value, y._value)); + + /// + public static NFloat MinMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitude(x._value, y._value)); + + /// + public static NFloat MinMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitudeNumber(x._value, y._value)); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out NFloat result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out NFloat result) { - return CreateSaturating(value); + return TryConvertFrom(value, out result); } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateSaturating(TOther value) + static bool INumberBase.TryConvertFromTruncating(TOther value, out NFloat result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out NFloat result) where TOther : INumberBase { if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return (NFloat)(decimal)(object)value; + decimal actualValue = (decimal)(object)value; + result = (NFloat)actualValue; + return true; } else if (typeof(TOther) == typeof(double)) { - return (NFloat)(double)(object)value; + double actualValue = (double)(object)value; + result = (NFloat)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(short)) { - return (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(int)) { - return (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(long)) { - return (long)(object)value; + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (NFloat)actualValue; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(float)) { - return (NFloat)(float)(object)value; + float actualValue = (float)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = (NFloat)actualValue; + return true; } - else if (typeof(TOther) == typeof(NFloat)) + else if (typeof(TOther) == typeof(nuint)) { - return (NFloat)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default!; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(NFloat value, [NotNullWhen(true)] out TOther result) { - return CreateChecked(value); + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = checked((Int128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } } - /// - static bool INumberBase.IsCanonical(NFloat value) => true; - - /// - static bool INumberBase.IsComplexNumber(NFloat value) => false; - - /// - public static bool IsEvenInteger(NFloat value) => NativeType.IsEvenInteger(value._value); - - /// - static bool INumberBase.IsImaginaryNumber(NFloat value) => false; - - /// - public static bool IsInteger(NFloat value) => NativeType.IsInteger(value._value); - - /// - public static bool IsOddInteger(NFloat value) => NativeType.IsOddInteger(value._value); - - /// - public static bool IsPositive(NFloat value) => NativeType.IsPositive(value._value); - - /// - public static bool IsRealNumber(NFloat value) => NativeType.IsRealNumber(value._value); - - /// - static bool INumberBase.IsZero(NFloat value) => (value == 0); - - /// - public static NFloat MaxMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitude(x._value, y._value)); - - /// - public static NFloat MaxMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitudeNumber(x._value, y._value)); - - /// - public static NFloat MinMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitude(x._value, y._value)); - - /// - public static NFloat MinMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitudeNumber(x._value, y._value)); + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(NFloat value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out NFloat result) + static bool INumberBase.TryConvertToTruncating(NFloat value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + private static bool TryConvertTo(NFloat value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase { - result = CreateSaturating(value); - return true; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value >= +79228162514264337593543950336.0f) ? decimal.MaxValue : + (value <= -79228162514264337593543950336.0f) ? decimal.MinValue : + IsNaN(value) ? 0.0m : (decimal)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult = (value >= short.MaxValue) ? short.MaxValue : + (value <= short.MinValue) ? short.MinValue : (short)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualResult = (value >= int.MaxValue) ? int.MaxValue : + (value <= int.MinValue) ? int.MinValue : (int)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualResult = (value >= long.MaxValue) ? long.MaxValue : + (value <= long.MinValue) ? long.MinValue : (long)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = (value >= +170141183460469231731687303715884105727.0) ? Int128.MaxValue : + (value <= -170141183460469231731687303715884105728.0) ? Int128.MinValue : (Int128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualResult = (value >= nint.MaxValue) ? nint.MaxValue : + (value <= nint.MinValue) ? nint.MinValue : (nint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue : + (value <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value >= ulong.MaxValue) ? ulong.MaxValue : + (value <= ulong.MinValue) ? ulong.MinValue : + IsNaN(value) ? 0 : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value >= 340282366920938463463374607431768211455.0) ? UInt128.MaxValue : + (value <= 0.0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { +#if TARGET_32BIT + nuint actualResult = (value >= uint.MaxValue) ? unchecked((nuint)uint.MaxValue) : + (value <= uint.MinValue) ? unchecked((nuint)uint.MinValue) : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#else + nuint actualResult = (value >= ulong.MaxValue) ? unchecked((nuint)ulong.MaxValue) : + (value <= ulong.MinValue) ? unchecked((nuint)ulong.MinValue) : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#endif + } + else + { + result = default!; + return false; + } } // diff --git a/src/libraries/System.Private.CoreLib/src/System/SByte.cs b/src/libraries/System.Private.CoreLib/src/System/SByte.cs index ff3edb4dd7ef8b..ac88c897ae997b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SByte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SByte.cs @@ -584,230 +584,6 @@ public static sbyte CopySign(sbyte value, sbyte sign) /// public static sbyte Abs(sbyte value) => Math.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return checked((sbyte)(byte)(object)value); - } - else if (typeof(TOther) == typeof(char)) - { - return checked((sbyte)(char)(object)value); - } - else if (typeof(TOther) == typeof(decimal)) - { - return checked((sbyte)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((sbyte)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((sbyte)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((sbyte)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((sbyte)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((sbyte)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return checked((sbyte)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return checked((sbyte)(ushort)(object)value); - } - else if (typeof(TOther) == typeof(uint)) - { - return checked((sbyte)(uint)(object)value); - } - else if (typeof(TOther) == typeof(ulong)) - { - return checked((sbyte)(ulong)(object)value); - } - else if (typeof(TOther) == typeof(nuint)) - { - return checked((sbyte)(nuint)(object)value); - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - var actualValue = (byte)(object)value; - return (actualValue > MaxValue) ? MaxValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(char)) - { - var actualValue = (char)(object)value; - return (actualValue > MaxValue) ? MaxValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(decimal)) - { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(double)) - { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(short)) - { - var actualValue = (short)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(int)) - { - var actualValue = (int)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(long)) - { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(nint)) - { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < MinValue) ? MinValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(ushort)) - { - var actualValue = (ushort)(object)value; - return (actualValue > MaxValue) ? MaxValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(uint)) - { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(ulong)) - { - var actualValue = (ulong)(object)value; - return (actualValue > (uint)MaxValue) ? MaxValue : (sbyte)actualValue; - } - else if (typeof(TOther) == typeof(nuint)) - { - var actualValue = (nuint)(object)value; - return (actualValue > (uint)MaxValue) ? MaxValue : (sbyte)actualValue; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (sbyte)(byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (sbyte)(char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (sbyte)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (sbyte)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (sbyte)(short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (sbyte)(int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (sbyte)(long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (sbyte)(nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (sbyte)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (sbyte)(ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (sbyte)(uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (sbyte)(ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (sbyte)(nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(sbyte value) => true; @@ -945,189 +721,421 @@ public static sbyte MinMagnitude(sbyte x, sbyte y) /// static sbyte INumberBase.MinMagnitudeNumber(sbyte x, sbyte y) => MinMagnitude(x, y); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out sbyte result) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out sbyte result) { - if (typeof(TOther) == typeof(byte)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((sbyte)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (byte)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (sbyte)actualValue; + Half actualValue = (Half)(object)value; + result = checked((sbyte)actualValue); return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (char)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (sbyte)actualValue; + short actualValue = (short)(object)value; + result = checked((sbyte)actualValue); return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (sbyte)actualValue; + int actualValue = (int)(object)value; + result = checked((sbyte)actualValue); return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (double)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + long actualValue = (long)(object)value; + result = checked((sbyte)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = checked((sbyte)actualValue); + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = checked((sbyte)actualValue); + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((sbyte)actualValue); + return true; + } + else + { + result = default; + return false; + } + } - result = (sbyte)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out sbyte result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; return true; } else if (typeof(TOther) == typeof(short)) { - var actualValue = (short)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + short actualValue = (short)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else + { + result = default; + return false; + } + } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out sbyte result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; result = (sbyte)actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - var actualValue = (int)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + int actualValue = (int)(object)value; result = (sbyte)actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - var actualValue = (long)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + long actualValue = (long)(object)value; result = (sbyte)actualValue; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (nint)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - + Int128 actualValue = (Int128)(object)value; result = (sbyte)actualValue; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(nint)) { - result = (sbyte)(object)value; + nint actualValue = (nint)(object)value; + result = (sbyte)actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - var actualValue = (float)(object)value; + float actualValue = (float)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (sbyte)actualValue; + return true; + } + else + { + result = default; + return false; + } + } - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(sbyte value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (sbyte)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (ushort)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (sbyte)actualValue; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (sbyte)actualValue; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (uint)MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(sbyte value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (sbyte)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value <= 0) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value <= 0) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value <= 0) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value <= 0) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value <= 0) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; + nuint actualResult = (value <= 0) ? 0 : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } - if (actualValue > (uint)MaxValue) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(sbyte value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `sbyte` will handle the other signed types and + // `ConvertTo` will handle the unsigned types - result = (sbyte)actualValue; + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (nuint)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 2ff1aad7fcfd49..96e413d938f3cb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -986,98 +986,6 @@ public static float MinNumber(float x, float y) /// public static float Abs(float value) => MathF.Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateChecked(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (float)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (float)(double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(Int128)) - { - return (float)(Int128)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(UInt128)) - { - return (float)(UInt128)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateTruncating(TOther value) - where TOther : INumberBase - { - return CreateSaturating(value); - } - /// static bool INumberBase.IsCanonical(float value) => true; @@ -1169,13 +1077,258 @@ public static float MinMagnitudeNumber(float x, float y) return y; } - /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out float result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out float result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out float result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out float result) + where TOther : INumberBase + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `float` will handle the other signed types and + // `ConvertTo` will handle the unsigned types + + if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = (float)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = (float)actualValue; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (float)actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else + { + result = default; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(float value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `float` will handle the other signed types and + // `ConvertTo` will handle the unsigned types. + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out float result) + static bool INumberBase.TryConvertToSaturating(float value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(float value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo(value, out result); + } + + private static bool TryConvertTo(float value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase { - result = CreateSaturating(value); - return true; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `float` will handle the other signed types and + // `ConvertTo` will handle the unsigned types. + + if (typeof(TOther) == typeof(byte)) + { + var actualResult = (value >= byte.MaxValue) ? byte.MaxValue : + (value <= byte.MinValue) ? byte.MinValue : (byte)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value >= char.MaxValue) ? char.MaxValue : + (value <= char.MinValue) ? char.MinValue : (char)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value >= +79228162514264337593543950336.0f) ? decimal.MaxValue : + (value <= -79228162514264337593543950336.0f) ? decimal.MinValue : + IsNaN(value) ? 0.0m : (decimal)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value >= ushort.MaxValue) ? ushort.MaxValue : + (value <= ushort.MinValue) ? ushort.MinValue : (ushort)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value >= ulong.MaxValue) ? ulong.MaxValue : + (value <= ulong.MinValue) ? ulong.MinValue : + IsNaN(value) ? 0 : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value == PositiveInfinity) ? UInt128.MaxValue : + (value <= 0.0f) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { +#if TARGET_64BIT + nuint actualResult = (value >= ulong.MaxValue) ? unchecked((nuint)ulong.MaxValue) : + (value <= ulong.MinValue) ? unchecked((nuint)ulong.MinValue) : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#else + nuint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + (value <= uint.MinValue) ? uint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; + return true; +#endif + } + else + { + result = default!; + return false; + } } // diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs index 90b370f61ea683..b2b9771ba567fc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs @@ -587,17 +587,6 @@ internal static UInt128 ToUInt128(double value) } } - /// Explicitly converts a value to a 128-bit unsigned integer. - /// The value to convert. - /// converted to a 128-bit unsigned integer. - public static explicit operator UInt128(Half value) => (UInt128)(double)(value); - - /// Explicitly converts a value to a 128-bit unsigned integer, throwing an overflow exception for any values that fall outside the representable range. - /// The value to convert. - /// converted to a 128-bit unsigned integer. - /// is not representable by . - public static explicit operator checked UInt128(Half value) => checked((UInt128)(double)(value)); - /// Explicitly converts a value to a 128-bit unsigned integer. /// The value to convert. /// converted to a 128-bit unsigned integer. @@ -1344,448 +1333,479 @@ public static UInt128 Clamp(UInt128 value, UInt128 min, UInt128 max) /// static UInt128 INumberBase.Abs(UInt128 value) => value; - /// + /// + static bool INumberBase.IsCanonical(UInt128 value) => true; + + /// + static bool INumberBase.IsComplexNumber(UInt128 value) => false; + + /// + public static bool IsEvenInteger(UInt128 value) => (value._lower & 1) == 0; + + /// + static bool INumberBase.IsFinite(UInt128 value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(UInt128 value) => false; + + /// + static bool INumberBase.IsInfinity(UInt128 value) => false; + + /// + static bool INumberBase.IsInteger(UInt128 value) => true; + + /// + static bool INumberBase.IsNaN(UInt128 value) => false; + + /// + static bool INumberBase.IsNegative(UInt128 value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(UInt128 value) => false; + + /// + static bool INumberBase.IsNormal(UInt128 value) => value != 0U; + + /// + public static bool IsOddInteger(UInt128 value) => (value._lower & 1) != 0; + + /// + static bool INumberBase.IsPositive(UInt128 value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(UInt128 value) => false; + + /// + static bool INumberBase.IsRealNumber(UInt128 value) => true; + + /// + static bool INumberBase.IsSubnormal(UInt128 value) => false; + + /// + static bool INumberBase.IsZero(UInt128 value) => (value == 0U); + + /// + static UInt128 INumberBase.MaxMagnitude(UInt128 x, UInt128 y) => Max(x, y); + + /// + static UInt128 INumberBase.MaxMagnitudeNumber(UInt128 x, UInt128 y) => Max(x, y); + + /// + static UInt128 INumberBase.MinMagnitude(UInt128 x, UInt128 y) => Min(x, y); + + /// + static UInt128 INumberBase.MinMagnitudeNumber(UInt128 x, UInt128 y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out UInt128 result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((UInt128)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((UInt128)(double)(object)value); - } - else if (typeof(TOther) == typeof(Half)) - { - return checked((UInt128)(Half)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((UInt128)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((UInt128)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((UInt128)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((UInt128)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((UInt128)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((UInt128)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((UInt128)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - return (nuint)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out UInt128 result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue < 0) ? MinValue : (UInt128)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(ushort)) { - return (UInt128)(double)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(Half)) + else if (typeof(TOther) == typeof(uint)) { - return (UInt128)(Half)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (short)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (int)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else { - var actualValue = (long)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(nint)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out UInt128 result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (nint)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(char)) { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; + char actualValue = (char)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(decimal)) { - return (UInt128)(float)(object)value; + decimal actualValue = (decimal)(object)value; + result = (actualValue < 0) ? MinValue : (UInt128)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - return (nuint)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(UInt128 value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - var actualValue = (decimal)(object)value; - return (actualValue < 0) ? MinValue : (UInt128)actualValue; - } - else if (typeof(TOther) == typeof(double)) + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) { - return (UInt128)(double)(object)value; + double actualResult = (double)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(Half)) { - return (UInt128)(Half)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (UInt128)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (UInt128)(int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (UInt128)(long)(object)value; + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = checked((Int128)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (UInt128)(nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (UInt128)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (UInt128)(float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; + float actualResult = (float)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(uint)) + else { - return (uint)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(ulong)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(UInt128 value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) { - return (ulong)(object)value; + double actualResult = (double)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(Half)) { - return (nuint)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(short)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + short actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_7FFF)) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(UInt128 value) => true; - - /// - static bool INumberBase.IsComplexNumber(UInt128 value) => false; - - /// - public static bool IsEvenInteger(UInt128 value) => (value._lower & 1) == 0; - - /// - static bool INumberBase.IsFinite(UInt128 value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(UInt128 value) => false; - - /// - static bool INumberBase.IsInfinity(UInt128 value) => false; - - /// - static bool INumberBase.IsInteger(UInt128 value) => true; - - /// - static bool INumberBase.IsNaN(UInt128 value) => false; - - /// - static bool INumberBase.IsNegative(UInt128 value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(UInt128 value) => false; - - /// - static bool INumberBase.IsNormal(UInt128 value) => value != 0U; - - /// - public static bool IsOddInteger(UInt128 value) => (value._lower & 1) != 0; - - /// - static bool INumberBase.IsPositive(UInt128 value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(UInt128 value) => false; - - /// - static bool INumberBase.IsRealNumber(UInt128 value) => true; - - /// - static bool INumberBase.IsSubnormal(UInt128 value) => false; - - /// - static bool INumberBase.IsZero(UInt128 value) => (value == 0U); - - /// - static UInt128 INumberBase.MaxMagnitude(UInt128 x, UInt128 y) => Max(x, y); - - /// - static UInt128 INumberBase.MaxMagnitudeNumber(UInt128 x, UInt128 y) => Max(x, y); - - /// - static UInt128 INumberBase.MinMagnitude(UInt128 x, UInt128 y) => Min(x, y); - - /// - static UInt128 INumberBase.MinMagnitudeNumber(UInt128 x, UInt128 y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out UInt128 result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(int)) { - result = (byte)(object)value; + int actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x0000_0000_7FFF_FFFF)) ? int.MaxValue : (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(long)) { - result = (char)(object)value; + long actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x7FFF_FFFF_FFFF_FFFF)) ? long.MaxValue : (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(Int128)) { - var actualValue = (decimal)(object)value; - - if (actualValue < 0.0m) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + Int128 actualResult = (value >= new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? Int128.MaxValue : (Int128)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0.0) || (actualValue >= +340282366920938463463374607431768211456.0) || double.IsNaN(actualValue)) - { - result = default; - return false; - } - - result = (UInt128)actualValue; +#if TARGET_32BIT + nint actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x0000_0000_7FFF_FFFF)) ? nint.MaxValue : (nint)value; + result = (TOther)(object)actualResult; + return true; +#else + nint actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x7FFF_FFFF_FFFF_FFFF)) ? nint.MaxValue : (nint)value; + result = (TOther)(object)actualResult; return true; +#endif } - else if (typeof(TOther) == typeof(Half)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (Half)(object)value; - - if ((actualValue < Half.Zero) || (actualValue > Half.MaxValue) || Half.IsNaN(actualValue)) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + sbyte actualResult = (value >= new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_007F)) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + float actualResult = (float)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; + result = default!; + return false; + } + } - if (actualValue < 0) - { - result = default; - return false; - } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(UInt128 value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `UInt128` will handle the other unsigned types and + // `ConvertTo` will handle the signed types - result = (UInt128)actualValue; + if (typeof(TOther) == typeof(double)) + { + double actualResult = (double)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + int actualResult = (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0.0f) || (actualValue > float.MaxValue) || float.IsNaN(actualValue)) - { - result = default; - return false; - } - - result = (UInt128)actualValue; + long actualResult = (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - result = (ushort)(object)value; + Int128 actualResult = (Int128)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - result = (uint)(object)value; + nint actualResult = (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - result = (ulong)(object)value; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - result = (nuint)(object)value; + float actualResult = (float)value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs index 97b6e6b7a884aa..3ef0feff7a90aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs @@ -526,457 +526,475 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static ushort INumberBase.Abs(ushort value) => value; - /// + /// + static bool INumberBase.IsCanonical(ushort value) => true; + + /// + static bool INumberBase.IsComplexNumber(ushort value) => false; + + /// + public static bool IsEvenInteger(ushort value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(ushort value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(ushort value) => false; + + /// + static bool INumberBase.IsInfinity(ushort value) => false; + + /// + static bool INumberBase.IsInteger(ushort value) => true; + + /// + static bool INumberBase.IsNaN(ushort value) => false; + + /// + static bool INumberBase.IsNegative(ushort value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(ushort value) => false; + + /// + static bool INumberBase.IsNormal(ushort value) => value != 0; + + /// + public static bool IsOddInteger(ushort value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(ushort value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(ushort value) => false; + + /// + static bool INumberBase.IsRealNumber(ushort value) => true; + + /// + static bool INumberBase.IsSubnormal(ushort value) => false; + + /// + static bool INumberBase.IsZero(ushort value) => (value == 0); + + /// + static ushort INumberBase.MaxMagnitude(ushort x, ushort y) => Max(x, y); + + /// + static ushort INumberBase.MaxMagnitudeNumber(ushort x, ushort y) => Max(x, y); + + /// + static ushort INumberBase.MinMagnitude(ushort x, ushort y) => Min(x, y); + + /// + static ushort INumberBase.MinMagnitudeNumber(ushort x, ushort y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out ushort result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((ushort)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((ushort)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((ushort)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((ushort)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((ushort)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((ushort)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((ushort)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((ushort)(float)(object)value); - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; + decimal actualValue = (decimal)(object)value; + result = checked((ushort)actualValue); + return true; } else if (typeof(TOther) == typeof(uint)) { - return checked((ushort)(uint)(object)value); + uint actualValue = (uint)(object)value; + result = checked((ushort)actualValue); + return true; } else if (typeof(TOther) == typeof(ulong)) { - return checked((ushort)(ulong)(object)value); + ulong actualValue = (ulong)(object)value; + result = checked((ushort)actualValue); + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = checked((ushort)actualValue); + return true; } else if (typeof(TOther) == typeof(nuint)) { - return checked((ushort)(nuint)(object)value); + nuint actualValue = (nuint)(object)value; + result = checked((ushort)actualValue); + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out ushort result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (ushort)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(uint)) { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + uint actualValue = (uint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (ushort)actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (short)(object)value; - return (actualValue < 0) ? MinValue : (ushort)actualValue; + ulong actualValue = (ulong)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (ushort)actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (int)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (ushort)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + nuint actualValue = (nuint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (ushort)actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(sbyte)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out ushort result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (ushort)actualValue; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(char)) { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ushort)actualValue; + char actualValue = (char)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(decimal)) { - return (ushort)(object)value; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (ushort)actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - var actualValue = (uint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (ushort)actualValue; + uint actualValue = (uint)(object)value; + result = (ushort)actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (ushort)actualValue; + ulong actualValue = (ulong)(object)value; + result = (ushort)actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (ushort)actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (ushort)actualValue; + nuint actualValue = (nuint)(object)value; + result = (ushort)actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(ushort value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (ushort)(decimal)(object)value; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (ushort)(double)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (ushort)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (ushort)(int)(object)value; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (ushort)(long)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (ushort)(nint)(object)value; + nint actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (ushort)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (ushort)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) - { - return (ushort)(uint)(object)value; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(ushort value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (ushort)(ulong)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (ushort)(nuint)(object)value; + short actualResult = (value >= short.MaxValue) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(ushort value) => true; - - /// - static bool INumberBase.IsComplexNumber(ushort value) => false; - - /// - public static bool IsEvenInteger(ushort value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(ushort value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(ushort value) => false; - - /// - static bool INumberBase.IsInfinity(ushort value) => false; - - /// - static bool INumberBase.IsInteger(ushort value) => true; - - /// - static bool INumberBase.IsNaN(ushort value) => false; - - /// - static bool INumberBase.IsNegative(ushort value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(ushort value) => false; - - /// - static bool INumberBase.IsNormal(ushort value) => value != 0; - - /// - public static bool IsOddInteger(ushort value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(ushort value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(ushort value) => false; - - /// - static bool INumberBase.IsRealNumber(ushort value) => true; - - /// - static bool INumberBase.IsSubnormal(ushort value) => false; - - /// - static bool INumberBase.IsZero(ushort value) => (value == 0); - - /// - static ushort INumberBase.MaxMagnitude(ushort x, ushort y) => Max(x, y); - - /// - static ushort INumberBase.MaxMagnitudeNumber(ushort x, ushort y) => Max(x, y); - - /// - static ushort INumberBase.MinMagnitude(ushort x, ushort y) => Min(x, y); - - /// - static ushort INumberBase.MinMagnitudeNumber(ushort x, ushort y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out ushort result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (byte)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - result = (char)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ushort)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ushort)actualValue; + sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ushort)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } + result = default!; + return false; + } + } - result = (ushort)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(ushort value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ushort` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ushort)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ushort)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ushort)actualValue; + int actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ushort)actualValue; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - result = (ushort)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (uint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (ushort)actualValue; + nint actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (ulong)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (ushort)actualValue; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (nuint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (ushort)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs index eddab867b0221c..93c27f43d5d069 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs @@ -512,447 +512,481 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static uint INumberBase.Abs(uint value) => value; - /// + /// + static bool INumberBase.IsCanonical(uint value) => true; + + /// + static bool INumberBase.IsComplexNumber(uint value) => false; + + /// + public static bool IsEvenInteger(uint value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(uint value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(uint value) => false; + + /// + static bool INumberBase.IsInfinity(uint value) => false; + + /// + static bool INumberBase.IsInteger(uint value) => true; + + /// + static bool INumberBase.IsNaN(uint value) => false; + + /// + static bool INumberBase.IsNegative(uint value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(uint value) => false; + + /// + static bool INumberBase.IsNormal(uint value) => value != 0; + + /// + public static bool IsOddInteger(uint value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(uint value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(uint value) => false; + + /// + static bool INumberBase.IsRealNumber(uint value) => true; + + /// + static bool INumberBase.IsSubnormal(uint value) => false; + + /// + static bool INumberBase.IsZero(uint value) => (value == 0); + + /// + static uint INumberBase.MaxMagnitude(uint x, uint y) => Max(x, y); + + /// + static uint INumberBase.MaxMagnitudeNumber(uint x, uint y) => Max(x, y); + + /// + static uint INumberBase.MinMagnitude(uint x, uint y) => Min(x, y); + + /// + static uint INumberBase.MinMagnitudeNumber(uint x, uint y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out uint result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((uint)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((uint)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((uint)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((uint)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((uint)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((uint)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((uint)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((uint)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((uint)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(ulong)) { - return (uint)(object)value; + ulong actualValue = (ulong)(object)value; + result = checked((uint)actualValue); + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(UInt128)) { - return checked((uint)(ulong)(object)value); + UInt128 actualValue = (UInt128)(object)value; + result = checked((uint)actualValue); + return true; } else if (typeof(TOther) == typeof(nuint)) { - return checked((uint)(nuint)(object)value); + nuint actualValue = (nuint)(object)value; + result = checked((uint)actualValue); + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out uint result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (uint)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (uint)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (uint)actualValue; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (short)(object)value; - return (actualValue < 0) ? MinValue : (uint)actualValue; + ulong actualValue = (ulong)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (uint)actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (int)(object)value; - return (actualValue < 0) ? MinValue : (uint)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (uint)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (long)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (uint)actualValue; + nuint actualValue = (nuint)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (uint)actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else { - var actualValue = (nint)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (uint)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(sbyte)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out uint result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (uint)actualValue; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(char)) { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (uint)actualValue; + char actualValue = (char)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(decimal)) { - return (ushort)(object)value; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (uint)actualValue; + return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(ushort)) { - return (uint)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; - return (actualValue > MaxValue) ? MaxValue : (uint)actualValue; + ulong actualValue = (ulong)(object)value; + result = (uint)actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (uint)actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (nuint)(object)value; - return (actualValue > MaxValue) ? MaxValue : (uint)actualValue; + nuint actualValue = (nuint)(object)value; + result = (uint)actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(uint value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (uint)(decimal)(object)value; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (uint)(double)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (uint)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (uint)(int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (uint)(long)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (uint)(nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (uint)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (uint)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(uint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (uint)(ulong)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (uint)(nuint)(object)value; + short actualResult = (value >= (uint)short.MaxValue) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = (value >= int.MaxValue) ? int.MaxValue : (int)value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(uint value) => true; - - /// - static bool INumberBase.IsComplexNumber(uint value) => false; - - /// - public static bool IsEvenInteger(uint value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(uint value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(uint value) => false; - - /// - static bool INumberBase.IsInfinity(uint value) => false; - - /// - static bool INumberBase.IsInteger(uint value) => true; - - /// - static bool INumberBase.IsNaN(uint value) => false; - - /// - static bool INumberBase.IsNegative(uint value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(uint value) => false; - - /// - static bool INumberBase.IsNormal(uint value) => value != 0; - - /// - public static bool IsOddInteger(uint value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(uint value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(uint value) => false; - - /// - static bool INumberBase.IsRealNumber(uint value) => true; - - /// - static bool INumberBase.IsSubnormal(uint value) => false; - - /// - static bool INumberBase.IsZero(uint value) => (value == 0); - - /// - static uint INumberBase.MaxMagnitude(uint x, uint y) => Max(x, y); - - /// - static uint INumberBase.MaxMagnitudeNumber(uint x, uint y) => Max(x, y); - - /// - static uint INumberBase.MinMagnitude(uint x, uint y) => Min(x, y); - - /// - static uint INumberBase.MinMagnitudeNumber(uint x, uint y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out uint result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (byte)(object)value; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - result = (char)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (uint)actualValue; +#if TARGET_32BIT + nint actualResult = (value >= int.MaxValue) ? int.MaxValue : (nint)value; + result = (TOther)(object)actualResult; return true; +#else + nint actualResult = (nint)value; + result = (TOther)(object)actualResult; + return true; +#endif } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (uint)actualValue; + sbyte actualResult = (value >= (uint)sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (uint)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } + result = default!; + return false; + } + } - result = (uint)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(uint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `uint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (uint)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (uint)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (uint)actualValue; + int actualResult = (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (uint)actualValue; + long actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - result = (ushort)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - result = (uint)(object)value; + nint actualResult = (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (ulong)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (uint)actualValue; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (nuint)(object)value; - - if (actualValue > MaxValue) - { - result = default; - return false; - } - - result = (uint)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs index 48607b8819fa9b..928163fa2a85ab 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs @@ -511,427 +511,475 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static ulong INumberBase.Abs(ulong value) => value; - /// + /// + static bool INumberBase.IsCanonical(ulong value) => true; + + /// + static bool INumberBase.IsComplexNumber(ulong value) => false; + + /// + public static bool IsEvenInteger(ulong value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(ulong value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(ulong value) => false; + + /// + static bool INumberBase.IsInfinity(ulong value) => false; + + /// + static bool INumberBase.IsInteger(ulong value) => true; + + /// + static bool INumberBase.IsNaN(ulong value) => false; + + /// + static bool INumberBase.IsNegative(ulong value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(ulong value) => false; + + /// + static bool INumberBase.IsNormal(ulong value) => value != 0; + + /// + public static bool IsOddInteger(ulong value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(ulong value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(ulong value) => false; + + /// + static bool INumberBase.IsRealNumber(ulong value) => true; + + /// + static bool INumberBase.IsSubnormal(ulong value) => false; + + /// + static bool INumberBase.IsZero(ulong value) => (value == 0); + + /// + static ulong INumberBase.MaxMagnitude(ulong x, ulong y) => Max(x, y); + + /// + static ulong INumberBase.MaxMagnitudeNumber(ulong x, ulong y) => Max(x, y); + + /// + static ulong INumberBase.MinMagnitude(ulong x, ulong y) => Min(x, y); + + /// + static ulong INumberBase.MinMagnitudeNumber(ulong x, ulong y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out ulong result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((ulong)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((ulong)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((ulong)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((ulong)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((ulong)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((ulong)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((ulong)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((ulong)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((ulong)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(UInt128)) { - return (ulong)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = checked((ulong)actualValue); + return true; } else if (typeof(TOther) == typeof(nuint)) { - return (nuint)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out ulong result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ulong)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (ulong)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (double)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ulong)actualValue; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(uint)) { - var actualValue = (short)(object)value; - return (actualValue < 0) ? MinValue : (ulong)actualValue; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (int)(object)value; - return (actualValue < 0) ? MinValue : (ulong)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : (ulong)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(nuint)) { - var actualValue = (long)(object)value; - return (actualValue < 0) ? MinValue : (ulong)actualValue; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else { - var actualValue = (nint)(object)value; - return (actualValue < 0) ? MinValue : (ulong)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(sbyte)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out ulong result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (ulong)actualValue; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(char)) { - var actualValue = (float)(object)value; - return (actualValue > MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (ulong)actualValue; + char actualValue = (char)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualValue = (decimal)(object)value; + result = (actualValue >= MaxValue) ? MaxValue : + (actualValue <= MinValue) ? MinValue : (ulong)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(UInt128)) { - return (ulong)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = (ulong)actualValue; + return true; } else if (typeof(TOther) == typeof(nuint)) { - return (nuint)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(ulong value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (ulong)(decimal)(object)value; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (ulong)(double)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (ulong)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (ulong)(int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (ulong)(long)(object)value; + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = checked((Int128)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (ulong)(nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (ulong)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (ulong)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(ulong value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (ulong)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (nuint)(object)value; + short actualResult = (value >= (ulong)short.MaxValue) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = (value >= int.MaxValue) ? int.MaxValue : (int)value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(ulong value) => true; - - /// - static bool INumberBase.IsComplexNumber(ulong value) => false; - - /// - public static bool IsEvenInteger(ulong value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(ulong value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(ulong value) => false; - - /// - static bool INumberBase.IsInfinity(ulong value) => false; - - /// - static bool INumberBase.IsInteger(ulong value) => true; - - /// - static bool INumberBase.IsNaN(ulong value) => false; - - /// - static bool INumberBase.IsNegative(ulong value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(ulong value) => false; - - /// - static bool INumberBase.IsNormal(ulong value) => value != 0; - - /// - public static bool IsOddInteger(ulong value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(ulong value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(ulong value) => false; - - /// - static bool INumberBase.IsRealNumber(ulong value) => true; - - /// - static bool INumberBase.IsSubnormal(ulong value) => false; - - /// - static bool INumberBase.IsZero(ulong value) => (value == 0); - - /// - static ulong INumberBase.MaxMagnitude(ulong x, ulong y) => Max(x, y); - - /// - static ulong INumberBase.MaxMagnitudeNumber(ulong x, ulong y) => Max(x, y); - - /// - static ulong INumberBase.MinMagnitude(ulong x, ulong y) => Min(x, y); - - /// - static ulong INumberBase.MinMagnitudeNumber(ulong x, ulong y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out ulong result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (byte)(object)value; + long actualResult = (value >= long.MaxValue) ? long.MaxValue : (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - result = (char)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ulong)actualValue; + nint actualResult = (value >= (ulong)nint.MaxValue) ? nint.MaxValue : (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ulong)actualValue; + sbyte actualResult = (value >= (ulong)sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ulong)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } + result = default!; + return false; + } + } - result = (ulong)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(ulong value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `ulong` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ulong)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ulong)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (ulong)actualValue; + int actualResult = (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < MinValue) || (actualValue > MaxValue)) - { - result = default; - return false; - } - - result = (ulong)actualValue; + long actualResult = (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - result = (ushort)(object)value; + Int128 actualResult = (Int128)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - result = (uint)(object)value; + nint actualResult = (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - result = (ulong)(object)value; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - result = (nuint)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs index 4795ef4df67bfe..48ef6b8103f2e4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs @@ -487,438 +487,475 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static nuint INumberBase.Abs(nuint value) => value; - /// + /// + static bool INumberBase.IsCanonical(nuint value) => true; + + /// + static bool INumberBase.IsComplexNumber(nuint value) => false; + + /// + public static bool IsEvenInteger(nuint value) => (value & 1) == 0; + + /// + static bool INumberBase.IsFinite(nuint value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(nuint value) => false; + + /// + static bool INumberBase.IsInfinity(nuint value) => false; + + /// + static bool INumberBase.IsInteger(nuint value) => true; + + /// + static bool INumberBase.IsNaN(nuint value) => false; + + /// + static bool INumberBase.IsNegative(nuint value) => false; + + /// + static bool INumberBase.IsNegativeInfinity(nuint value) => false; + + /// + static bool INumberBase.IsNormal(nuint value) => value != 0; + + /// + public static bool IsOddInteger(nuint value) => (value & 1) != 0; + + /// + static bool INumberBase.IsPositive(nuint value) => true; + + /// + static bool INumberBase.IsPositiveInfinity(nuint value) => false; + + /// + static bool INumberBase.IsRealNumber(nuint value) => true; + + /// + static bool INumberBase.IsSubnormal(nuint value) => false; + + /// + static bool INumberBase.IsZero(nuint value) => (value == 0); + + /// + static nuint INumberBase.MaxMagnitude(nuint x, nuint y) => Max(x, y); + + /// + static nuint INumberBase.MaxMagnitudeNumber(nuint x, nuint y) => Max(x, y); + + /// + static nuint INumberBase.MinMagnitude(nuint x, nuint y) => Min(x, y); + + /// + static nuint INumberBase.MinMagnitudeNumber(nuint x, nuint y) => Min(x, y); + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromChecked(TOther value, out nuint result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((nuint)(decimal)(object)value); - } - else if (typeof(TOther) == typeof(double)) - { - return checked((nuint)(double)(object)value); - } - else if (typeof(TOther) == typeof(short)) - { - return checked((nuint)(short)(object)value); - } - else if (typeof(TOther) == typeof(int)) - { - return checked((nuint)(int)(object)value); - } - else if (typeof(TOther) == typeof(long)) - { - return checked((nuint)(long)(object)value); - } - else if (typeof(TOther) == typeof(nint)) - { - return checked((nuint)(nint)(object)value); - } - else if (typeof(TOther) == typeof(sbyte)) - { - return checked((nuint)(sbyte)(object)value); - } - else if (typeof(TOther) == typeof(float)) - { - return checked((nuint)(float)(object)value); + decimal actualValue = (decimal)(object)value; + result = checked((nuint)actualValue); + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return checked((nuint)(ulong)(object)value); + ulong actualValue = (ulong)(object)value; + result = checked((nuint)actualValue); + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = checked((nuint)actualValue); + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out nuint result) { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - var actualValue = (decimal)(object)value; - return (actualValue > nuint.MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (nuint)actualValue; + decimal actualValue = (decimal)(object)value; + result = (actualValue >= nuint_t.MaxValue) ? unchecked((nuint)nuint_t.MaxValue) : + (actualValue <= nuint_t.MinValue) ? unchecked((nuint)nuint_t.MinValue) : (nuint)actualValue; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(ushort)) { - var actualValue = (double)(object)value; - return (actualValue > nuint.MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (nuint)actualValue; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(uint)) { - var actualValue = (short)(object)value; - return (actualValue < 0) ? MinValue : (nuint)actualValue; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (int)(object)value; - return (actualValue < 0) ? MinValue : (nuint)actualValue; + ulong actualValue = (ulong)(object)value; + result = (actualValue >= nuint_t.MaxValue) ? unchecked((nuint)nuint_t.MaxValue) : (nuint)actualValue; + return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(UInt128)) { - var actualValue = (long)(object)value; - - return ((Size == 4) && (actualValue > uint.MaxValue)) ? MaxValue : - (actualValue < 0) ? MinValue : (nuint)actualValue; + UInt128 actualValue = (UInt128)(object)value; + result = (actualValue >= nuint_t.MaxValue) ? unchecked((nuint)nuint_t.MaxValue) : (nuint)actualValue; + return true; } - else if (typeof(TOther) == typeof(nint)) + else { - var actualValue = (nint)(object)value; - return (actualValue < 0) ? MinValue : (nuint)actualValue; + result = default; + return false; } - else if (typeof(TOther) == typeof(sbyte)) + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromTruncating(TOther value, out nuint result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(byte)) { - var actualValue = (sbyte)(object)value; - return (actualValue < 0) ? MinValue : (nuint)actualValue; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(char)) { - var actualValue = (float)(object)value; - return (actualValue > nuint.MaxValue) ? MaxValue : - (actualValue < 0) ? MinValue : (nuint)actualValue; + char actualValue = (char)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualValue = (decimal)(object)value; + result = (actualValue >= nuint_t.MaxValue) ? unchecked((nuint)nuint_t.MaxValue) : + (actualValue <= nuint_t.MinValue) ? unchecked((nuint)nuint_t.MinValue) : (nuint)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - var actualValue = (ulong)(object)value; - return (actualValue > nuint.MaxValue) ? MaxValue : (nuint)actualValue; + ulong actualValue = (ulong)(object)value; + result = (nuint)actualValue; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = (nuint)actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(nuint value, [NotNullWhen(true)] out TOther result) { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (nuint)(decimal)(object)value; + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(Half)) { - return (nuint)(double)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (nuint)(short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (nuint)(int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (nuint)(long)(object)value; + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (nuint)(nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (nuint)(sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (nuint)(float)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ushort)) + else { - return (ushort)(object)value; + result = default!; + return false; } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(nuint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(Half)) { - return (nuint)(ulong)(object)value; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(short)) { - return (nuint)(object)value; + short actualResult = (value >= (nuint)short.MaxValue) ? short.MaxValue : (short)value; + result = (TOther)(object)actualResult; + return true; } - else + else if (typeof(TOther) == typeof(int)) { - ThrowHelper.ThrowNotSupportedException(); - return default; + int actualResult = (value >= int.MaxValue) ? int.MaxValue : (int)value; + result = (TOther)(object)actualResult; + return true; } - } - - /// - static bool INumberBase.IsCanonical(nuint value) => true; - - /// - static bool INumberBase.IsComplexNumber(nuint value) => false; - - /// - public static bool IsEvenInteger(nuint value) => (value & 1) == 0; - - /// - static bool INumberBase.IsFinite(nuint value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(nuint value) => false; - - /// - static bool INumberBase.IsInfinity(nuint value) => false; - - /// - static bool INumberBase.IsInteger(nuint value) => true; - - /// - static bool INumberBase.IsNaN(nuint value) => false; - - /// - static bool INumberBase.IsNegative(nuint value) => false; - - /// - static bool INumberBase.IsNegativeInfinity(nuint value) => false; - - /// - static bool INumberBase.IsNormal(nuint value) => value != 0; - - /// - public static bool IsOddInteger(nuint value) => (value & 1) != 0; - - /// - static bool INumberBase.IsPositive(nuint value) => true; - - /// - static bool INumberBase.IsPositiveInfinity(nuint value) => false; - - /// - static bool INumberBase.IsRealNumber(nuint value) => true; - - /// - static bool INumberBase.IsSubnormal(nuint value) => false; - - /// - static bool INumberBase.IsZero(nuint value) => (value == 0); - - /// - static nuint INumberBase.MaxMagnitude(nuint x, nuint y) => Max(x, y); - - /// - static nuint INumberBase.MaxMagnitudeNumber(nuint x, nuint y) => Max(x, y); - - /// - static nuint INumberBase.MinMagnitude(nuint x, nuint y) => Min(x, y); - - /// - static nuint INumberBase.MinMagnitudeNumber(nuint x, nuint y) => Min(x, y); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out nuint result) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) + else if (typeof(TOther) == typeof(long)) { - result = (byte)(object)value; + long actualResult = (value >= long.MaxValue) ? long.MaxValue : (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(char)) + else if (typeof(TOther) == typeof(Int128)) { - result = (char)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(decimal)) + else if (typeof(TOther) == typeof(nint)) { - var actualValue = (decimal)(object)value; - - if ((actualValue < 0) || (actualValue > nuint.MaxValue)) - { - result = default; - return false; - } - - result = (nuint)actualValue; + nint actualResult = (value >= (nuint)nint.MaxValue) ? nint.MaxValue : (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(double)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (double)(object)value; - - if ((actualValue < 0) || (actualValue > nuint.MaxValue)) - { - result = default; - return false; - } - - result = (nuint)actualValue; + sbyte actualResult = (value >= (nuint)sbyte.MaxValue) ? sbyte.MaxValue : (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(float)) { - var actualValue = (short)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (nuint)actualValue; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else { - var actualValue = (int)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } + result = default!; + return false; + } + } - result = (nuint)actualValue; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(nuint value, [NotNullWhen(true)] out TOther result) + { + // In order to reduce overall code duplication and improve the inlinabilty of these + // methods for the corelib types we have `ConvertFrom` handle the same sign and + // `ConvertTo` handle the opposite sign. However, since there is an uneven split + // between signed and unsigned types, the one that handles unsigned will also + // handle `Decimal`. + // + // That is, `ConvertFrom` for `nuint` will handle the other unsigned types and + // `ConvertTo` will handle the signed types + + if (typeof(TOther) == typeof(double)) + { + double actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Half)) { - var actualValue = (long)(object)value; - - if ((actualValue < 0) || ((Size == 4) && (actualValue > uint.MaxValue))) - { - result = default; - return false; - } - - result = (nuint)actualValue; + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nint)) + else if (typeof(TOther) == typeof(short)) { - var actualValue = (nint)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (nuint)actualValue; + short actualResult = (short)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(int)) { - var actualValue = (sbyte)(object)value; - - if (actualValue < 0) - { - result = default; - return false; - } - - result = (nuint)actualValue; + int actualResult = (int)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(long)) { - var actualValue = (float)(object)value; - - if ((actualValue < 0) || (actualValue > nuint.MaxValue)) - { - result = default; - return false; - } - - result = (nuint)actualValue; + long actualResult = (long)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ushort)) + else if (typeof(TOther) == typeof(Int128)) { - result = (ushort)(object)value; + Int128 actualResult = value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(uint)) + else if (typeof(TOther) == typeof(nint)) { - result = (uint)(object)value; + nint actualResult = (nint)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(ulong)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (ulong)(object)value; - - if (actualValue > nuint.MaxValue) - { - result = default; - return false; - } - - result = (nuint)actualValue; + sbyte actualResult = (sbyte)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(float)) { - result = (nuint)(object)value; + float actualResult = value; + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 7d59b44cdad1ce..cbff7ff2612e37 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -853,9 +853,6 @@ public static void Free(void* ptr) { } public static System.Runtime.InteropServices.NFloat CopySign(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat Cos(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Cosh(System.Runtime.InteropServices.NFloat x) { throw null; } - public static System.Runtime.InteropServices.NFloat CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Runtime.InteropServices.NFloat CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Runtime.InteropServices.NFloat CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.Runtime.InteropServices.NFloat other) { throw null; } public static System.Runtime.InteropServices.NFloat Exp(System.Runtime.InteropServices.NFloat x) { throw null; } @@ -899,14 +896,36 @@ public static void Free(void* ptr) { } public static System.Runtime.InteropServices.NFloat MinMagnitudeNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MinNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat operator +(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } + public static explicit operator checked byte (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked char (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked short (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked int (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked long (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked System.Int128 (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator checked nint (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked sbyte (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked ushort (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked uint (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked ulong (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked System.UInt128 (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked nuint (System.Runtime.InteropServices.NFloat value) { throw null; } public static System.Runtime.InteropServices.NFloat operator --(System.Runtime.InteropServices.NFloat value) { throw null; } public static System.Runtime.InteropServices.NFloat operator /(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } public static bool operator ==(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } public static explicit operator System.Runtime.InteropServices.NFloat (decimal value) { throw null; } public static explicit operator System.Runtime.InteropServices.NFloat (double value) { throw null; } + public static explicit operator System.Runtime.InteropServices.NFloat (System.Int128 value) { throw null; } public static explicit operator byte (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator char (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator decimal (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator System.Half (System.Runtime.InteropServices.NFloat value) { throw null; } + public static explicit operator System.Int128 (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator short (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator int (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator long (System.Runtime.InteropServices.NFloat value) { throw null; } @@ -915,6 +934,8 @@ public static void Free(void* ptr) { } public static explicit operator sbyte (System.Runtime.InteropServices.NFloat value) { throw null; } public static explicit operator float (System.Runtime.InteropServices.NFloat value) { throw null; } [System.CLSCompliantAttribute(false)] + public static explicit operator System.UInt128 (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] public static explicit operator ushort (System.Runtime.InteropServices.NFloat value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator uint (System.Runtime.InteropServices.NFloat value) { throw null; } @@ -922,6 +943,8 @@ public static void Free(void* ptr) { } public static explicit operator ulong (System.Runtime.InteropServices.NFloat value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator nuint (System.Runtime.InteropServices.NFloat value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Runtime.InteropServices.NFloat (System.UInt128 value) { throw null; } public static bool operator >(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } public static bool operator >=(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } public static implicit operator System.Runtime.InteropServices.NFloat (byte value) { throw null; } @@ -930,6 +953,7 @@ public static void Free(void* ptr) { } public static implicit operator System.Runtime.InteropServices.NFloat (int value) { throw null; } public static implicit operator System.Runtime.InteropServices.NFloat (long value) { throw null; } public static implicit operator System.Runtime.InteropServices.NFloat (nint value) { throw null; } + public static implicit operator System.Runtime.InteropServices.NFloat (System.Half value) { throw null; } public static implicit operator double (System.Runtime.InteropServices.NFloat value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Runtime.InteropServices.NFloat (sbyte value) { throw null; } @@ -991,6 +1015,12 @@ public static void Free(void* ptr) { } static bool System.Numerics.INumberBase.IsComplexNumber(System.Runtime.InteropServices.NFloat value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(System.Runtime.InteropServices.NFloat value) { throw null; } static bool System.Numerics.INumberBase.IsZero(System.Runtime.InteropServices.NFloat value) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Runtime.InteropServices.NFloat System.Numerics.ISubtractionOperators.operator checked -(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } static System.Runtime.InteropServices.NFloat System.Numerics.IUnaryNegationOperators.operator checked -(System.Runtime.InteropServices.NFloat value) { throw null; } public static System.Runtime.InteropServices.NFloat Tan(System.Runtime.InteropServices.NFloat x) { throw null; } @@ -1000,7 +1030,6 @@ public static void Free(void* ptr) { } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static System.Runtime.InteropServices.NFloat Truncate(System.Runtime.InteropServices.NFloat x) { throw null; } - public static bool TryCreate(TOther value, out System.Runtime.InteropServices.NFloat result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Runtime.InteropServices.NFloat result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.Runtime.InteropServices.NFloat result) { throw null; } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj index 657ccd9f4af449..5216e69b0d12ed 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj @@ -15,7 +15,6 @@ - @@ -149,6 +148,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.GenericMath.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.GenericMath.cs index 3e842bd7ab1fe9..00e3c9601aed76 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.GenericMath.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.GenericMath.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Tests; using Xunit; namespace System.Runtime.InteropServices.Tests @@ -1532,6 +1533,105 @@ public static void CreateCheckedFromCharTest() AssertBitwiseEqual((NFloat)65535.0f, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateChecked(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateChecked(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateChecked(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateChecked(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateChecked(double.MaxValue)); + } + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateChecked(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -1580,6 +1680,25 @@ public static void CreateCheckedFromInt64Test() } } + [Fact] + public static void CreateCheckedFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper.CreateChecked(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper.CreateChecked(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateChecked(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateChecked(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -1601,6 +1720,34 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1611,6 +1758,32 @@ public static void CreateCheckedFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper.CreateChecked(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper.CreateChecked(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper.CreateChecked(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper.CreateChecked(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper.CreateChecked(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper.CreateChecked(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper.CreateChecked(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper.CreateChecked(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1661,6 +1834,26 @@ public static void CreateCheckedFromUInt64Test() } } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper.CreateChecked(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper.CreateChecked(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper.CreateChecked(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper.CreateChecked(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper.CreateChecked(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateChecked(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateChecked(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -1706,6 +1899,105 @@ public static void CreateSaturatingFromCharTest() AssertBitwiseEqual((NFloat)65535.0f, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(+1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.MaxValue)); + } + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateSaturating(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -1754,6 +2046,25 @@ public static void CreateSaturatingFromInt64Test() } } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper.CreateSaturating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper.CreateSaturating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateSaturating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateSaturating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -1775,6 +2086,34 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1785,6 +2124,32 @@ public static void CreateSaturatingFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper.CreateSaturating(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper.CreateSaturating(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper.CreateSaturating(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper.CreateSaturating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper.CreateSaturating(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper.CreateSaturating(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper.CreateSaturating(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1835,6 +2200,26 @@ public static void CreateSaturatingFromUInt64Test() } } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper.CreateSaturating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper.CreateSaturating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper.CreateSaturating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper.CreateSaturating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper.CreateSaturating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateSaturating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateSaturating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1880,6 +2265,105 @@ public static void CreateTruncatingFromCharTest() AssertBitwiseEqual((NFloat)65535.0f, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.MaxValue)); + } + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateTruncating(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -1928,6 +2412,25 @@ public static void CreateTruncatingFromInt64Test() } } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper.CreateTruncating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper.CreateTruncating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateTruncating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateTruncating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -1949,6 +2452,34 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1959,6 +2490,32 @@ public static void CreateTruncatingFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper.CreateTruncating(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper.CreateTruncating(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper.CreateTruncating(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper.CreateTruncating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper.CreateTruncating(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper.CreateTruncating(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper.CreateTruncating(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -2009,6 +2566,26 @@ public static void CreateTruncatingFromUInt64Test() } } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper.CreateTruncating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper.CreateTruncating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper.CreateTruncating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper.CreateTruncating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper.CreateTruncating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -2454,329 +3031,6 @@ public static void MinMagnitudeNumberTest() AssertBitwiseEqual(One, NumberBaseHelper.MinMagnitudeNumber(NFloat.PositiveInfinity, One)); } - [Fact] - public static void TryCreateFromByteTest() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((NFloat)127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((NFloat)128.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((NFloat)255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((NFloat)32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((NFloat)65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((NFloat)(-32768.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0f), result); - } - } - - [Fact] - public static void TryCreateFromInt64Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(NegativeOne, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal((NFloat)(-9223372036854775808.0), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal((NFloat)(-9223372036854775808.0f), result); - } - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - NFloat result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((NFloat)(-9223372036854775808.0), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((NFloat)127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((NFloat)(-128.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((NFloat)32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((NFloat)65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((NFloat)2147483648.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((NFloat)4294967295.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((NFloat)2147483648.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((NFloat)4294967295.0f, result); - } - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - NFloat result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((NFloat)9223372036854775808.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((NFloat)9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)18446744073709551615.0f, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - NFloat result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal((NFloat)9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal((NFloat)18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - // Assert.Equal((NFloat)2147483648.0f, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal((NFloat)4294967295.0f, result); - } - } - // // ISignedNumber // diff --git a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs index a7a99ca8c232f0..8c09f8a7db6e90 100644 --- a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs +++ b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs @@ -44,9 +44,6 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public int CompareTo(ulong other) { throw null; } public static System.Numerics.BigInteger CopySign(System.Numerics.BigInteger value, System.Numerics.BigInteger sign) { throw null; } - public static System.Numerics.BigInteger CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Numerics.BigInteger CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Numerics.BigInteger CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static System.Numerics.BigInteger Divide(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor) { throw null; } public static (System.Numerics.BigInteger Quotient, System.Numerics.BigInteger Remainder) DivRem(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } public static System.Numerics.BigInteger DivRem(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor, out System.Numerics.BigInteger remainder) { throw null; } @@ -91,19 +88,22 @@ namespace System.Numerics public static System.Numerics.BigInteger operator ^(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } public static explicit operator System.Numerics.BigInteger (decimal value) { throw null; } public static explicit operator System.Numerics.BigInteger (double value) { throw null; } + public static explicit operator System.Numerics.BigInteger (System.Half value) { throw null; } public static explicit operator byte (System.Numerics.BigInteger value) { throw null; } + public static explicit operator char (System.Numerics.BigInteger value) { throw null; } public static explicit operator decimal (System.Numerics.BigInteger value) { throw null; } public static explicit operator double (System.Numerics.BigInteger value) { throw null; } - public static explicit operator System.Int128(System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.Half (System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.Int128 (System.Numerics.BigInteger value) { throw null; } public static explicit operator short (System.Numerics.BigInteger value) { throw null; } public static explicit operator int (System.Numerics.BigInteger value) { throw null; } public static explicit operator long (System.Numerics.BigInteger value) { throw null; } - public static explicit operator nint (System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.IntPtr (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator sbyte (System.Numerics.BigInteger value) { throw null; } public static explicit operator float (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator System.UInt128(System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.UInt128 (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator ushort (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -111,7 +111,8 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static explicit operator ulong (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator nuint (System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.UIntPtr (System.Numerics.BigInteger value) { throw null; } + public static explicit operator System.Numerics.BigInteger (System.Numerics.Complex value) { throw null; } public static explicit operator System.Numerics.BigInteger (float value) { throw null; } public static bool operator >(long left, System.Numerics.BigInteger right) { throw null; } public static bool operator >(System.Numerics.BigInteger left, long right) { throw null; } @@ -128,11 +129,12 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static bool operator >=(ulong left, System.Numerics.BigInteger right) { throw null; } public static implicit operator System.Numerics.BigInteger (byte value) { throw null; } + public static implicit operator System.Numerics.BigInteger (char value) { throw null; } public static implicit operator System.Numerics.BigInteger (System.Int128 value) { throw null; } public static implicit operator System.Numerics.BigInteger (short value) { throw null; } public static implicit operator System.Numerics.BigInteger (int value) { throw null; } public static implicit operator System.Numerics.BigInteger (long value) { throw null; } - public static implicit operator System.Numerics.BigInteger (nint value) { throw null; } + public static implicit operator System.Numerics.BigInteger (System.IntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.BigInteger (sbyte value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -144,7 +146,7 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.BigInteger (ulong value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator System.Numerics.BigInteger (nuint value) { throw null; } + public static implicit operator System.Numerics.BigInteger (System.UIntPtr value) { throw null; } public static System.Numerics.BigInteger operator ++(System.Numerics.BigInteger value) { throw null; } public static bool operator !=(long left, System.Numerics.BigInteger right) { throw null; } public static bool operator !=(System.Numerics.BigInteger left, long right) { throw null; } @@ -212,6 +214,12 @@ namespace System.Numerics static bool System.Numerics.INumberBase.IsZero(System.Numerics.BigInteger value) { throw null; } static System.Numerics.BigInteger System.Numerics.INumberBase.MaxMagnitudeNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static System.Numerics.BigInteger System.Numerics.INumberBase.MinMagnitudeNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Numerics.BigInteger System.Numerics.INumber.MaxNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static System.Numerics.BigInteger System.Numerics.INumber.MinNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static int System.Numerics.INumber.Sign(System.Numerics.BigInteger value) { throw null; } @@ -224,7 +232,6 @@ namespace System.Numerics public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static System.Numerics.BigInteger TrailingZeroCount(System.Numerics.BigInteger value) { throw null; } - public static bool TryCreate(TOther value, out System.Numerics.BigInteger result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan value, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.BigInteger result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.Numerics.BigInteger result) { throw null; } @@ -263,9 +270,6 @@ namespace System.Numerics public static System.Numerics.Complex Conjugate(System.Numerics.Complex value) { throw null; } public static System.Numerics.Complex Cos(System.Numerics.Complex value) { throw null; } public static System.Numerics.Complex Cosh(System.Numerics.Complex value) { throw null; } - public static System.Numerics.Complex CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Numerics.Complex CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Numerics.Complex CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static System.Numerics.Complex Divide(double dividend, System.Numerics.Complex divisor) { throw null; } public static System.Numerics.Complex Divide(System.Numerics.Complex dividend, double divisor) { throw null; } public static System.Numerics.Complex Divide(System.Numerics.Complex dividend, System.Numerics.Complex divisor) { throw null; } @@ -307,12 +311,18 @@ namespace System.Numerics public static System.Numerics.Complex operator /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } public static bool operator ==(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } public static explicit operator System.Numerics.Complex (decimal value) { throw null; } + public static explicit operator System.Numerics.Complex (System.Int128 value) { throw null; } public static explicit operator System.Numerics.Complex (System.Numerics.BigInteger value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Numerics.Complex (System.UInt128 value) { throw null; } public static implicit operator System.Numerics.Complex (byte value) { throw null; } + public static implicit operator System.Numerics.Complex (char value) { throw null; } public static implicit operator System.Numerics.Complex (double value) { throw null; } + public static implicit operator System.Numerics.Complex (System.Half value) { throw null; } public static implicit operator System.Numerics.Complex (short value) { throw null; } public static implicit operator System.Numerics.Complex (int value) { throw null; } public static implicit operator System.Numerics.Complex (long value) { throw null; } + public static implicit operator System.Numerics.Complex (System.IntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.Complex (sbyte value) { throw null; } public static implicit operator System.Numerics.Complex (float value) { throw null; } @@ -322,6 +332,8 @@ namespace System.Numerics public static implicit operator System.Numerics.Complex (uint value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.Complex (ulong value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static implicit operator System.Numerics.Complex (System.UIntPtr value) { throw null; } public static System.Numerics.Complex operator ++(System.Numerics.Complex value) { throw null; } public static bool operator !=(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } public static System.Numerics.Complex operator *(double left, System.Numerics.Complex right) { throw null; } @@ -355,6 +367,12 @@ namespace System.Numerics static bool System.Numerics.INumberBase.IsZero(System.Numerics.Complex value) { throw null; } static System.Numerics.Complex System.Numerics.INumberBase.MaxMagnitudeNumber(System.Numerics.Complex x, System.Numerics.Complex y) { throw null; } static System.Numerics.Complex System.Numerics.INumberBase.MinMagnitudeNumber(System.Numerics.Complex x, System.Numerics.Complex y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Numerics.Complex System.Numerics.ISubtractionOperators.operator checked -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } static System.Numerics.Complex System.Numerics.IUnaryNegationOperators.operator checked -(System.Numerics.Complex value) { throw null; } public static System.Numerics.Complex Tan(System.Numerics.Complex value) { throw null; } @@ -363,7 +381,6 @@ namespace System.Numerics public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } - public static bool TryCreate(TOther value, out System.Numerics.Complex result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, System.ReadOnlySpan format, System.IFormatProvider? provider) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.Complex result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.Numerics.Complex result) { throw null; } diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index e079da8ca7c497..39c8346a54ee43 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -1742,199 +1742,87 @@ private static BigInteger Subtract(ReadOnlySpan leftBits, int leftSign, Re return result; } - public static implicit operator BigInteger(byte value) - { - return new BigInteger(value); - } - - [CLSCompliant(false)] - public static implicit operator BigInteger(sbyte value) - { - return new BigInteger(value); - } - - public static implicit operator BigInteger(short value) - { - return new BigInteger(value); - } + // + // Explicit Conversions From BigInteger + // - [CLSCompliant(false)] - public static implicit operator BigInteger(ushort value) + public static explicit operator byte(BigInteger value) { - return new BigInteger(value); + return checked((byte)((int)value)); } - public static implicit operator BigInteger(int value) + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. + public static explicit operator char(BigInteger value) { - return new BigInteger(value); + return checked((char)((int)value)); } - [CLSCompliant(false)] - public static implicit operator BigInteger(uint value) + public static explicit operator decimal(BigInteger value) { - return new BigInteger(value); - } + value.AssertValid(); + if (value._bits == null) + return value._sign; - public static implicit operator BigInteger(long value) - { - return new BigInteger(value); - } + int length = value._bits.Length; + if (length > 3) throw new OverflowException(SR.Overflow_Decimal); - [CLSCompliant(false)] - public static implicit operator BigInteger(ulong value) - { - return new BigInteger(value); - } + int lo = 0, mi = 0, hi = 0; - public static implicit operator BigInteger(nint value) - { - if (Environment.Is64BitProcess) - { - return new BigInteger(value); - } - else + unchecked { - return new BigInteger((int)value); + if (length > 2) hi = (int)value._bits[2]; + if (length > 1) mi = (int)value._bits[1]; + if (length > 0) lo = (int)value._bits[0]; } - } - [CLSCompliant(false)] - public static implicit operator BigInteger(nuint value) - { - if (Environment.Is64BitProcess) - { - return new BigInteger(value); - } - else - { - return new BigInteger((uint)value); - } + return new decimal(lo, mi, hi, value._sign < 0, 0); } - public static implicit operator BigInteger(Int128 value) + public static explicit operator double(BigInteger value) { - int sign; - uint[]? bits; + value.AssertValid(); - if ((int.MinValue < value) && (value <= int.MaxValue)) - { - sign = (int)value; - bits = null; - } - else if (value == int.MinValue) - { - return s_bnMinInt; - } - else - { - UInt128 x; - if (value < 0) - { - x = unchecked((UInt128)(-value)); - sign = -1; - } - else - { - x = (UInt128)value; - sign = +1; - } + int sign = value._sign; + uint[]? bits = value._bits; - if (x <= uint.MaxValue) - { - bits = new uint[1]; - bits[0] = (uint)(x >> (kcbitUint * 0)); - } - else if (x <= ulong.MaxValue) - { - bits = new uint[2]; - bits[0] = (uint)(x >> (kcbitUint * 0)); - bits[1] = (uint)(x >> (kcbitUint * 1)); - } - else if (x <= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) - { - bits = new uint[3]; - bits[0] = (uint)(x >> (kcbitUint * 0)); - bits[1] = (uint)(x >> (kcbitUint * 1)); - bits[2] = (uint)(x >> (kcbitUint * 2)); - } - else - { - bits = new uint[4]; - bits[0] = (uint)(x >> (kcbitUint * 0)); - bits[1] = (uint)(x >> (kcbitUint * 1)); - bits[2] = (uint)(x >> (kcbitUint * 2)); - bits[3] = (uint)(x >> (kcbitUint * 3)); - } - } + if (bits == null) + return sign; - return new BigInteger(sign, bits); - } + int length = bits.Length; - [CLSCompliant(false)] - public static implicit operator BigInteger(UInt128 value) - { - int sign = +1; - uint[]? bits; + // The maximum exponent for doubles is 1023, which corresponds to a uint bit length of 32. + // All BigIntegers with bits[] longer than 32 evaluate to Double.Infinity (or NegativeInfinity). + // Cases where the exponent is between 1024 and 1035 are handled in NumericsHelpers.GetDoubleFromParts. + const int InfinityLength = 1024 / kcbitUint; - if (value <= (uint)int.MaxValue) - { - sign = (int)value; - bits = null; - } - else if (value <= uint.MaxValue) - { - bits = new uint[1]; - bits[0] = (uint)(value >> (kcbitUint * 0)); - } - else if (value <= ulong.MaxValue) - { - bits = new uint[2]; - bits[0] = (uint)(value >> (kcbitUint * 0)); - bits[1] = (uint)(value >> (kcbitUint * 1)); - } - else if (value <= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) - { - bits = new uint[3]; - bits[0] = (uint)(value >> (kcbitUint * 0)); - bits[1] = (uint)(value >> (kcbitUint * 1)); - bits[2] = (uint)(value >> (kcbitUint * 2)); - } - else + if (length > InfinityLength) { - bits = new uint[4]; - bits[0] = (uint)(value >> (kcbitUint * 0)); - bits[1] = (uint)(value >> (kcbitUint * 1)); - bits[2] = (uint)(value >> (kcbitUint * 2)); - bits[3] = (uint)(value >> (kcbitUint * 3)); + if (sign == 1) + return double.PositiveInfinity; + else + return double.NegativeInfinity; } - return new BigInteger(sign, bits); - } - - public static explicit operator BigInteger(float value) - { - return new BigInteger(value); - } + ulong h = bits[length - 1]; + ulong m = length > 1 ? bits[length - 2] : 0; + ulong l = length > 2 ? bits[length - 3] : 0; - public static explicit operator BigInteger(double value) - { - return new BigInteger(value); - } + int z = BitOperations.LeadingZeroCount((uint)h); - public static explicit operator BigInteger(decimal value) - { - return new BigInteger(value); - } + int exp = (length - 2) * 32 - z; + ulong man = (h << 32 + z) | (m << z) | (l >> 32 - z); - public static explicit operator byte(BigInteger value) - { - return checked((byte)((int)value)); + return NumericsHelpers.GetDoubleFromParts(sign, exp, man); } - [CLSCompliant(false)] - public static explicit operator sbyte(BigInteger value) + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. + public static explicit operator Half(BigInteger value) { - return checked((sbyte)((int)value)); + return (Half)(double)value; } public static explicit operator short(BigInteger value) @@ -1942,12 +1830,6 @@ public static explicit operator short(BigInteger value) return checked((short)((int)value)); } - [CLSCompliant(false)] - public static explicit operator ushort(BigInteger value) - { - return checked((ushort)((int)value)); - } - public static explicit operator int(BigInteger value) { value.AssertValid(); @@ -1972,24 +1854,6 @@ public static explicit operator int(BigInteger value) return unchecked(-(int)value._bits[0]); } - [CLSCompliant(false)] - public static explicit operator uint(BigInteger value) - { - value.AssertValid(); - if (value._bits == null) - { - return checked((uint)value._sign); - } - else if (value._bits.Length > 1 || value._sign < 0) - { - throw new OverflowException(SR.Overflow_UInt32); - } - else - { - return value._bits[0]; - } - } - public static explicit operator long(BigInteger value) { value.AssertValid(); @@ -2023,28 +1887,9 @@ public static explicit operator long(BigInteger value) throw new OverflowException(SR.Overflow_Int64); } - [CLSCompliant(false)] - public static explicit operator ulong(BigInteger value) - { - value.AssertValid(); - if (value._bits == null) - { - return checked((ulong)value._sign); - } - - int len = value._bits.Length; - if (len > 2 || value._sign < 0) - { - throw new OverflowException(SR.Overflow_UInt64); - } - - if (len > 1) - { - return NumericsHelpers.MakeUInt64(value._bits[1], value._bits[0]); - } - return value._bits[0]; - } - + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. public static explicit operator Int128(BigInteger value) { value.AssertValid(); @@ -2089,14 +1934,89 @@ public static explicit operator Int128(BigInteger value) throw new OverflowException(SR.Overflow_Int128); } - [CLSCompliant(false)] - public static explicit operator UInt128(BigInteger value) + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. + public static explicit operator nint(BigInteger value) { - value.AssertValid(); - - if (value._bits is null) + if (Environment.Is64BitProcess) { - return checked((UInt128)value._sign); + return (nint)(long)value; + } + else + { + return (int)value; + } + } + + [CLSCompliant(false)] + public static explicit operator sbyte(BigInteger value) + { + return checked((sbyte)((int)value)); + } + + public static explicit operator float(BigInteger value) + { + return (float)((double)value); + } + + [CLSCompliant(false)] + public static explicit operator ushort(BigInteger value) + { + return checked((ushort)((int)value)); + } + + [CLSCompliant(false)] + public static explicit operator uint(BigInteger value) + { + value.AssertValid(); + if (value._bits == null) + { + return checked((uint)value._sign); + } + else if (value._bits.Length > 1 || value._sign < 0) + { + throw new OverflowException(SR.Overflow_UInt32); + } + else + { + return value._bits[0]; + } + } + + [CLSCompliant(false)] + public static explicit operator ulong(BigInteger value) + { + value.AssertValid(); + if (value._bits == null) + { + return checked((ulong)value._sign); + } + + int len = value._bits.Length; + if (len > 2 || value._sign < 0) + { + throw new OverflowException(SR.Overflow_UInt64); + } + + if (len > 1) + { + return NumericsHelpers.MakeUInt64(value._bits[1], value._bits[0]); + } + return value._bits[0]; + } + + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. + [CLSCompliant(false)] + public static explicit operator UInt128(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return checked((UInt128)value._sign); } int len = value._bits.Length; @@ -2120,92 +2040,252 @@ public static explicit operator UInt128(BigInteger value) return value._bits[0]; } - public static explicit operator nint(BigInteger value) + /// Explicitly converts a big integer to a value. + /// The value to convert. + /// converted to value. + [CLSCompliant(false)] + public static explicit operator nuint(BigInteger value) { if (Environment.Is64BitProcess) { - return (nint)(long)value; + return (nuint)(ulong)value; } else { - return (int)value; + return (uint)value; } } - [CLSCompliant(false)] - public static explicit operator nuint(BigInteger value) + // + // Explicit Conversions To BigInteger + // + + public static explicit operator BigInteger(decimal value) { - if (Environment.Is64BitProcess) - { - return (nuint)(ulong)value; - } - else + return new BigInteger(value); + } + + public static explicit operator BigInteger(double value) + { + return new BigInteger(value); + } + + /// Explicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + public static explicit operator BigInteger(Half value) + { + return new BigInteger((float)value); + } + + /// Explicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + public static explicit operator BigInteger(Complex value) + { + if (value.Imaginary != 0) { - return (uint)value; + ThrowHelper.ThrowOverflowException(); } + return (BigInteger)value.Real; } - public static explicit operator float(BigInteger value) + public static explicit operator BigInteger(float value) { - return (float)((double)value); + return new BigInteger(value); } - public static explicit operator double(BigInteger value) + // + // Implicit Conversions To BigInteger + // + + public static implicit operator BigInteger(byte value) { - value.AssertValid(); + return new BigInteger(value); + } - int sign = value._sign; - uint[]? bits = value._bits; + /// Implicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + public static implicit operator BigInteger(char value) + { + return new BigInteger(value); + } - if (bits == null) - return sign; + public static implicit operator BigInteger(short value) + { + return new BigInteger(value); + } - int length = bits.Length; + public static implicit operator BigInteger(int value) + { + return new BigInteger(value); + } - // The maximum exponent for doubles is 1023, which corresponds to a uint bit length of 32. - // All BigIntegers with bits[] longer than 32 evaluate to Double.Infinity (or NegativeInfinity). - // Cases where the exponent is between 1024 and 1035 are handled in NumericsHelpers.GetDoubleFromParts. - const int InfinityLength = 1024 / kcbitUint; + public static implicit operator BigInteger(long value) + { + return new BigInteger(value); + } - if (length > InfinityLength) + /// Implicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + public static implicit operator BigInteger(Int128 value) + { + int sign; + uint[]? bits; + + if ((int.MinValue < value) && (value <= int.MaxValue)) { - if (sign == 1) - return double.PositiveInfinity; + sign = (int)value; + bits = null; + } + else if (value == int.MinValue) + { + return s_bnMinInt; + } + else + { + UInt128 x; + if (value < 0) + { + x = unchecked((UInt128)(-value)); + sign = -1; + } else - return double.NegativeInfinity; + { + x = (UInt128)value; + sign = +1; + } + + if (x <= uint.MaxValue) + { + bits = new uint[1]; + bits[0] = (uint)(x >> (kcbitUint * 0)); + } + else if (x <= ulong.MaxValue) + { + bits = new uint[2]; + bits[0] = (uint)(x >> (kcbitUint * 0)); + bits[1] = (uint)(x >> (kcbitUint * 1)); + } + else if (x <= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) + { + bits = new uint[3]; + bits[0] = (uint)(x >> (kcbitUint * 0)); + bits[1] = (uint)(x >> (kcbitUint * 1)); + bits[2] = (uint)(x >> (kcbitUint * 2)); + } + else + { + bits = new uint[4]; + bits[0] = (uint)(x >> (kcbitUint * 0)); + bits[1] = (uint)(x >> (kcbitUint * 1)); + bits[2] = (uint)(x >> (kcbitUint * 2)); + bits[3] = (uint)(x >> (kcbitUint * 3)); + } } - ulong h = bits[length - 1]; - ulong m = length > 1 ? bits[length - 2] : 0; - ulong l = length > 2 ? bits[length - 3] : 0; + return new BigInteger(sign, bits); + } - int z = BitOperations.LeadingZeroCount((uint)h); + /// Implicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + public static implicit operator BigInteger(nint value) + { + if (Environment.Is64BitProcess) + { + return new BigInteger(value); + } + else + { + return new BigInteger((int)value); + } + } - int exp = (length - 2) * 32 - z; - ulong man = (h << 32 + z) | (m << z) | (l >> 32 - z); + [CLSCompliant(false)] + public static implicit operator BigInteger(sbyte value) + { + return new BigInteger(value); + } - return NumericsHelpers.GetDoubleFromParts(sign, exp, man); + [CLSCompliant(false)] + public static implicit operator BigInteger(ushort value) + { + return new BigInteger(value); } - public static explicit operator decimal(BigInteger value) + [CLSCompliant(false)] + public static implicit operator BigInteger(uint value) { - value.AssertValid(); - if (value._bits == null) - return value._sign; + return new BigInteger(value); + } - int length = value._bits.Length; - if (length > 3) throw new OverflowException(SR.Overflow_Decimal); + [CLSCompliant(false)] + public static implicit operator BigInteger(ulong value) + { + return new BigInteger(value); + } - int lo = 0, mi = 0, hi = 0; + /// Implicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + [CLSCompliant(false)] + public static implicit operator BigInteger(UInt128 value) + { + int sign = +1; + uint[]? bits; - unchecked + if (value <= (uint)int.MaxValue) + { + sign = (int)value; + bits = null; + } + else if (value <= uint.MaxValue) + { + bits = new uint[1]; + bits[0] = (uint)(value >> (kcbitUint * 0)); + } + else if (value <= ulong.MaxValue) + { + bits = new uint[2]; + bits[0] = (uint)(value >> (kcbitUint * 0)); + bits[1] = (uint)(value >> (kcbitUint * 1)); + } + else if (value <= new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) + { + bits = new uint[3]; + bits[0] = (uint)(value >> (kcbitUint * 0)); + bits[1] = (uint)(value >> (kcbitUint * 1)); + bits[2] = (uint)(value >> (kcbitUint * 2)); + } + else + { + bits = new uint[4]; + bits[0] = (uint)(value >> (kcbitUint * 0)); + bits[1] = (uint)(value >> (kcbitUint * 1)); + bits[2] = (uint)(value >> (kcbitUint * 2)); + bits[3] = (uint)(value >> (kcbitUint * 3)); + } + + return new BigInteger(sign, bits); + } + + /// Implicitly converts a value to a big integer. + /// The value to convert. + /// converted to a big integer. + [CLSCompliant(false)] + public static implicit operator BigInteger(nuint value) + { + if (Environment.Is64BitProcess) { - if (length > 2) hi = (int)value._bits[2]; - if (length > 1) mi = (int)value._bits[1]; - if (length > 0) lo = (int)value._bits[0]; + return new BigInteger(value); + } + else + { + return new BigInteger((uint)value); } - - return new decimal(lo, mi, hi, value._sign < 0, 0); } public static BigInteger operator &(BigInteger left, BigInteger right) @@ -3837,504 +3917,1231 @@ static void ThrowMinMaxException(T min, T max) { throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max)); } - } - - /// - public static BigInteger CopySign(BigInteger value, BigInteger sign) - { - value.AssertValid(); - sign.AssertValid(); - - int currentSign = value._sign; - - if (value._bits is null) + } + + /// + public static BigInteger CopySign(BigInteger value, BigInteger sign) + { + value.AssertValid(); + sign.AssertValid(); + + int currentSign = value._sign; + + if (value._bits is null) + { + currentSign = (currentSign >= 0) ? 1 : -1; + } + + int targetSign = sign._sign; + + if (sign._bits is null) + { + targetSign = (targetSign >= 0) ? 1 : -1; + } + + return (currentSign == targetSign) ? value : -value; + } + + /// + static BigInteger INumber.MaxNumber(BigInteger x, BigInteger y) => Max(x, y); + + /// + static BigInteger INumber.MinNumber(BigInteger x, BigInteger y) => Min(x, y); + + /// + static int INumber.Sign(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return int.Sign(value._sign); + } + + return value._sign; + } + + // + // INumberBase + // + + /// + static int INumberBase.Radix => 2; + + /// + static bool INumberBase.IsCanonical(BigInteger value) => true; + + /// + static bool INumberBase.IsComplexNumber(BigInteger value) => false; + + /// + public static bool IsEvenInteger(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return (value._sign & 1) == 0; + } + return (value._bits[0] & 1) == 0; + } + + /// + static bool INumberBase.IsFinite(BigInteger value) => true; + + /// + static bool INumberBase.IsImaginaryNumber(BigInteger value) => false; + + /// + static bool INumberBase.IsInfinity(BigInteger value) => false; + + /// + static bool INumberBase.IsInteger(BigInteger value) => true; + + /// + static bool INumberBase.IsNaN(BigInteger value) => false; + + /// + public static bool IsNegative(BigInteger value) + { + value.AssertValid(); + return value._sign < 0; + } + + /// + static bool INumberBase.IsNegativeInfinity(BigInteger value) => false; + + /// + static bool INumberBase.IsNormal(BigInteger value) => (value != 0); + + /// + public static bool IsOddInteger(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return (value._sign & 1) != 0; + } + return (value._bits[0] & 1) != 0; + } + + /// + public static bool IsPositive(BigInteger value) + { + value.AssertValid(); + return value._sign >= 0; + } + + /// + static bool INumberBase.IsPositiveInfinity(BigInteger value) => false; + + /// + static bool INumberBase.IsRealNumber(BigInteger value) => true; + + /// + static bool INumberBase.IsSubnormal(BigInteger value) => false; + + /// + static bool INumberBase.IsZero(BigInteger value) + { + value.AssertValid(); + return value._sign == 0; + } + + /// + public static BigInteger MaxMagnitude(BigInteger x, BigInteger y) + { + x.AssertValid(); + y.AssertValid(); + + BigInteger ax = Abs(x); + BigInteger ay = Abs(y); + + if (ax > ay) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? y : x; + } + + return y; + } + + /// + static BigInteger INumberBase.MaxMagnitudeNumber(BigInteger x, BigInteger y) => MaxMagnitude(x, y); + + /// + public static BigInteger MinMagnitude(BigInteger x, BigInteger y) + { + x.AssertValid(); + y.AssertValid(); + + BigInteger ax = Abs(x); + BigInteger ay = Abs(y); + + if (ax < ay) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? x : y; + } + + return y; + } + + /// + static BigInteger INumberBase.MinMagnitudeNumber(BigInteger x, BigInteger y) => MinMagnitude(x, y); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out BigInteger result) + { + if (typeof(TOther) == typeof(byte)) + { + byte actualValue = (byte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualValue = (char)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualValue = (decimal)(object)value; + result = (BigInteger)actualValue; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualValue = (double)(object)value; + result = checked((BigInteger)actualValue); + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = checked((BigInteger)actualValue); + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualValue = (short)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualValue = (nint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualValue = (float)(object)value; + result = checked((BigInteger)actualValue); + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualValue = (uint)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) { - currentSign = (currentSign >= 0) ? 1 : -1; + UInt128 actualValue = (UInt128)(object)value; + result = actualValue; + return true; } - - int targetSign = sign._sign; - - if (sign._bits is null) + else if (typeof(TOther) == typeof(nuint)) { - targetSign = (targetSign >= 0) ? 1 : -1; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } - - return (currentSign == targetSign) ? value : -value; - } - - /// - static BigInteger INumber.MaxNumber(BigInteger x, BigInteger y) => Max(x, y); - - /// - static BigInteger INumber.MinNumber(BigInteger x, BigInteger y) => Min(x, y); - - /// - static int INumber.Sign(BigInteger value) - { - value.AssertValid(); - - if (value._bits is null) + else { - return int.Sign(value._sign); + result = default; + return false; } - - return value._sign; } - // - // INumberBase - // - - /// - static int INumberBase.Radix => 2; - - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateChecked(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromSaturating(TOther value, out BigInteger result) { if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return checked((BigInteger)(decimal)(object)value); + decimal actualValue = (decimal)(object)value; + result = (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(double)) { - return checked((BigInteger)(double)(object)value); + double actualValue = (double)(object)value; + result = double.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = Half.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(short)) { - return (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(int)) { - return (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(long)) { - return (long)(object)value; + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(float)) { - return checked((BigInteger)(float)(object)value); + float actualValue = (float)(object)value; + result = float.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(BigInteger)) + else if (typeof(TOther) == typeof(nuint)) { - return (BigInteger)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateSaturating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertFromTruncating(TOther value, out BigInteger result) { if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return (BigInteger)(decimal)(object)value; + decimal actualValue = (decimal)(object)value; + result = (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(double)) { - return (BigInteger)(double)(object)value; + double actualValue = (double)(object)value; + result = double.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = Half.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(short)) { - return (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(int)) { - return (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(long)) { - return (long)(object)value; + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(float)) { - return (BigInteger)(float)(object)value; + float actualValue = (float)(object)value; + result = float.IsNaN(actualValue) ? Zero : (BigInteger)actualValue; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualValue = (UInt128)(object)value; + result = actualValue; + return true; } - else if (typeof(TOther) == typeof(BigInteger)) + else if (typeof(TOther) == typeof(nuint)) { - return (BigInteger)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default; + return false; } } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateTruncating(TOther value) - where TOther : INumberBase + static bool INumberBase.TryConvertToChecked(BigInteger value, [NotNullWhen(true)] out TOther result) { if (typeof(TOther) == typeof(byte)) { - return (byte)(object)value; + byte actualResult = checked((byte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(char)) { - return (char)(object)value; + char actualResult = checked((char)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(decimal)) { - return (BigInteger)(decimal)(object)value; + decimal actualResult = checked((decimal)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(double)) { - return (BigInteger)(double)(object)value; + double actualResult = (double)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(short)) { - return (short)(object)value; + short actualResult = checked((short)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(int)) { - return (int)(object)value; + int actualResult = checked((int)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(long)) { - return (long)(object)value; + long actualResult = checked((long)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = checked((Int128)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(nint)) { - return (nint)(object)value; + nint actualResult = checked((nint)value); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Complex)) + { + Complex actualResult = (Complex)value; + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(sbyte)) { - return (sbyte)(object)value; + sbyte actualResult = checked((sbyte)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(float)) { - return (BigInteger)(float)(object)value; + float actualResult = checked((float)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(ushort)) { - return (ushort)(object)value; + ushort actualResult = checked((ushort)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(uint)) { - return (uint)(object)value; + uint actualResult = checked((uint)value); + result = (TOther)(object)actualResult; + return true; } else if (typeof(TOther) == typeof(ulong)) { - return (ulong)(object)value; + ulong actualResult = checked((ulong)value); + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - return (nuint)(object)value; + UInt128 actualResult = checked((UInt128)value); + result = (TOther)(object)actualResult; + return true; } - else if (typeof(TOther) == typeof(BigInteger)) + else if (typeof(TOther) == typeof(nuint)) { - return (BigInteger)(object)value; + nuint actualResult = checked((nuint)value); + result = (TOther)(object)actualResult; + return true; } else { - ThrowHelper.ThrowNotSupportedException(); - return default; + result = default!; + return false; } } - /// - static bool INumberBase.IsCanonical(BigInteger value) => true; - - /// - static bool INumberBase.IsComplexNumber(BigInteger value) => false; - - /// - public static bool IsEvenInteger(BigInteger value) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(BigInteger value, [NotNullWhen(true)] out TOther result) { - value.AssertValid(); - - if (value._bits is null) + if (typeof(TOther) == typeof(byte)) { - return (value._sign & 1) == 0; - } - return (value._bits[0] & 1) == 0; - } - - /// - static bool INumberBase.IsFinite(BigInteger value) => true; - - /// - static bool INumberBase.IsImaginaryNumber(BigInteger value) => false; - - /// - static bool INumberBase.IsInfinity(BigInteger value) => false; - - /// - static bool INumberBase.IsInteger(BigInteger value) => true; - - /// - static bool INumberBase.IsNaN(BigInteger value) => false; + byte actualResult; - /// - public static bool IsNegative(BigInteger value) - { - value.AssertValid(); - return value._sign < 0; - } - - /// - static bool INumberBase.IsNegativeInfinity(BigInteger value) => false; + if (value._bits is not null) + { + actualResult = IsNegative(value) ? byte.MinValue : byte.MaxValue; + } + else + { + actualResult = (value._sign >= byte.MaxValue) ? byte.MaxValue : + (value._sign <= byte.MinValue) ? byte.MinValue : (byte)value._sign; + } - /// - static bool INumberBase.IsNormal(BigInteger value) => (value != 0); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult; - /// - public static bool IsOddInteger(BigInteger value) - { - value.AssertValid(); + if (value._bits is not null) + { + actualResult = IsNegative(value) ? char.MinValue : char.MaxValue; + } + else + { + actualResult = (value._sign >= char.MaxValue) ? char.MaxValue : + (value._sign <= char.MinValue) ? char.MinValue : (char)value._sign; + } - if (value._bits is null) + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) { - return (value._sign & 1) != 0; + decimal actualResult = (value >= new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? decimal.MaxValue : + (value <= new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)) ? decimal.MinValue : (decimal)value; + result = (TOther)(object)actualResult; + return true; } - return (value._bits[0] & 1) != 0; - } - - /// - public static bool IsPositive(BigInteger value) - { - value.AssertValid(); - return value._sign >= 0; - } - - /// - static bool INumberBase.IsPositiveInfinity(BigInteger value) => false; - - /// - static bool INumberBase.IsRealNumber(BigInteger value) => true; - - /// - static bool INumberBase.IsSubnormal(BigInteger value) => false; + else if (typeof(TOther) == typeof(double)) + { + double actualResult = (double)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult; - /// - static bool INumberBase.IsZero(BigInteger value) - { - value.AssertValid(); - return value._sign == 0; - } + if (value._bits is not null) + { + actualResult = IsNegative(value) ? short.MinValue : short.MaxValue; + } + else + { + actualResult = (value._sign >= short.MaxValue) ? short.MaxValue : + (value._sign <= short.MinValue) ? short.MinValue : (short)value._sign; + } - /// - public static BigInteger MaxMagnitude(BigInteger x, BigInteger y) - { - x.AssertValid(); - y.AssertValid(); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualResult; - BigInteger ax = Abs(x); - BigInteger ay = Abs(y); + if (value._bits is not null) + { + actualResult = IsNegative(value) ? int.MinValue : int.MaxValue; + } + else + { + actualResult = (value._sign >= int.MaxValue) ? int.MaxValue : + (value._sign <= int.MinValue) ? int.MinValue : (int)value._sign; + } - if (ax > ay) + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualResult = (value >= long.MaxValue) ? long.MaxValue : + (value <= long.MinValue) ? long.MinValue : (long)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) { - return x; + Int128 actualResult = (value >= Int128.MaxValue) ? Int128.MaxValue : + (value <= Int128.MinValue) ? Int128.MinValue : (Int128)value; + result = (TOther)(object)actualResult; + return true; } - - if (ax == ay) + else if (typeof(TOther) == typeof(nint)) { - return IsNegative(x) ? y : x; + nint actualResult = (value >= nint.MaxValue) ? nint.MaxValue : + (value <= nint.MinValue) ? nint.MinValue : (nint)value; + result = (TOther)(object)actualResult; + return true; } + else if (typeof(TOther) == typeof(Complex)) + { + Complex actualResult = (Complex)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult; - return y; - } - - /// - static BigInteger INumberBase.MaxMagnitudeNumber(BigInteger x, BigInteger y) => MaxMagnitude(x, y); + if (value._bits is not null) + { + actualResult = IsNegative(value) ? sbyte.MinValue : sbyte.MaxValue; + } + else + { + actualResult = (value._sign >= sbyte.MaxValue) ? sbyte.MaxValue : + (value._sign <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value._sign; + } - /// - public static BigInteger MinMagnitude(BigInteger x, BigInteger y) - { - x.AssertValid(); - y.AssertValid(); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult; - BigInteger ax = Abs(x); - BigInteger ay = Abs(y); + if (value._bits is not null) + { + actualResult = IsNegative(value) ? ushort.MinValue : ushort.MaxValue; + } + else + { + actualResult = (value._sign >= ushort.MaxValue) ? ushort.MaxValue : + (value._sign <= ushort.MinValue) ? ushort.MinValue : (ushort)value._sign; + } - if (ax < ay) + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) { - return x; + uint actualResult = (value >= uint.MaxValue) ? uint.MaxValue : + IsNegative(value) ? uint.MinValue : (uint)value; + result = (TOther)(object)actualResult; + return true; } - - if (ax == ay) + else if (typeof(TOther) == typeof(ulong)) { - return IsNegative(x) ? x : y; + ulong actualResult = (value >= ulong.MaxValue) ? ulong.MaxValue : + IsNegative(value) ? ulong.MinValue : (ulong)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value >= UInt128.MaxValue) ? UInt128.MaxValue : + IsNegative(value) ? UInt128.MinValue : (UInt128)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (value >= nuint.MaxValue) ? nuint.MaxValue : + IsNegative(value) ? nuint.MinValue : (nuint)value; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; } - - return y; } - /// - static BigInteger INumberBase.MinMagnitudeNumber(BigInteger x, BigInteger y) => MinMagnitude(x, y); - - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out BigInteger result) - where TOther : INumberBase + static bool INumberBase.TryConvertToTruncating(BigInteger value, [NotNullWhen(true)] out TOther result) { if (typeof(TOther) == typeof(byte)) { - result = (byte)(object)value; + byte actualResult; + + if (value._bits is not null) + { + uint bits = value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (byte)bits; + } + else + { + actualResult = (byte)value._sign; + } + + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(char)) { - result = (char)(object)value; + char actualResult; + + if (value._bits is not null) + { + uint bits = value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (char)bits; + } + else + { + actualResult = (char)value._sign; + } + + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(decimal)) { - result = (BigInteger)(decimal)(object)value; + decimal actualResult = (value >= new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)) ? decimal.MaxValue : + (value <= new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)) ? decimal.MinValue : (decimal)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(double)) { - var actualValue = (double)(object)value; + double actualResult = (double)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult; - if (!double.IsFinite(actualValue)) + if (value._bits is not null) { - result = default; - return false; + actualResult = IsNegative(value) ? (short)(~value._bits[0] + 1) : (short)value._bits[0]; + } + else + { + actualResult = (short)value._sign; } - result = (BigInteger)actualValue; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(short)) + else if (typeof(TOther) == typeof(int)) { - result = (short)(object)value; + int actualResult; + + if (value._bits is not null) + { + actualResult = IsNegative(value) ? (int)(~value._bits[0] + 1) : (int)value._bits[0]; + } + else + { + actualResult = value._sign; + } + + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(int)) + else if (typeof(TOther) == typeof(long)) { - result = (int)(object)value; + long actualResult; + + if (value._bits is not null) + { + ulong bits = 0; + + if (value._bits.Length >= 2) + { + bits = value._bits[1]; + bits <<= 32; + } + + bits |= value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (long)bits; + } + else + { + actualResult = value._sign; + } + + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(long)) + else if (typeof(TOther) == typeof(Int128)) { - result = (long)(object)value; + Int128 actualResult; + + if (value._bits is not null) + { + ulong lowerBits = 0; + ulong upperBits = 0; + + if (value._bits.Length >= 4) + { + upperBits = value._bits[3]; + upperBits <<= 32; + } + + if (value._bits.Length >= 3) + { + upperBits = value._bits[2]; + } + + if (value._bits.Length >= 2) + { + lowerBits = value._bits[1]; + lowerBits <<= 32; + } + + lowerBits |= value._bits[0]; + + UInt128 bits = new UInt128(upperBits, lowerBits); + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (Int128)bits; + } + else + { + actualResult = value._sign; + } + + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(nint)) { - result = (nint)(object)value; + nint actualResult; + + if (value._bits is not null) + { + nuint bits = 0; + + if (Environment.Is64BitProcess && (value._bits.Length >= 2)) + { + bits = value._bits[1]; + bits <<= 32; + } + + bits |= value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (nint)bits; + } + else + { + actualResult = value._sign; + } + + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(sbyte)) + else if (typeof(TOther) == typeof(Complex)) { - result = (sbyte)(object)value; + Complex actualResult = (Complex)value; + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(float)) + else if (typeof(TOther) == typeof(sbyte)) { - var actualValue = (float)(object)value; + sbyte actualResult; - if (!float.IsFinite(actualValue)) + if (value._bits is not null) { - result = default; - return false; + actualResult = IsNegative(value) ? (sbyte)(~value._bits[0] + 1) : (sbyte)value._bits[0]; + } + else + { + actualResult = (sbyte)value._sign; } - result = (BigInteger)actualValue; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value; + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualResult; + + if (value._bits is not null) + { + uint bits = value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = (ushort)bits; + } + else + { + actualResult = (ushort)value._sign; + } + + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(uint)) { - result = (uint)(object)value; + uint actualResult; + + if (value._bits is not null) + { + uint bits = value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = bits; + } + else + { + actualResult = (uint)value._sign; + } + + result = (TOther)(object)actualResult; return true; } else if (typeof(TOther) == typeof(ulong)) { - result = (ulong)(object)value; + ulong actualResult; + + if (value._bits is not null) + { + ulong bits = 0; + + if (value._bits.Length >= 2) + { + bits = value._bits[1]; + bits <<= 32; + } + + bits |= value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = bits; + } + else + { + actualResult = (ulong)value._sign; + } + + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(nuint)) + else if (typeof(TOther) == typeof(UInt128)) { - result = (nuint)(object)value; + UInt128 actualResult; + + if (value._bits is not null) + { + ulong lowerBits = 0; + ulong upperBits = 0; + + if (value._bits.Length >= 4) + { + upperBits = value._bits[3]; + upperBits <<= 32; + } + + if (value._bits.Length >= 3) + { + upperBits |= value._bits[2]; + } + + if (value._bits.Length >= 2) + { + lowerBits = value._bits[1]; + lowerBits <<= 32; + } + + lowerBits |= value._bits[0]; + + UInt128 bits = new UInt128(upperBits, lowerBits); + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = bits; + } + else + { + actualResult = (UInt128)value._sign; + } + + result = (TOther)(object)actualResult; return true; } - else if (typeof(TOther) == typeof(BigInteger)) + else if (typeof(TOther) == typeof(nuint)) { - result = (BigInteger)(object)value; + nuint actualResult; + + if (value._bits is not null) + { + nuint bits = 0; + + if (Environment.Is64BitProcess && (value._bits.Length >= 2)) + { + bits = value._bits[1]; + bits <<= 32; + } + + bits |= value._bits[0]; + + if (IsNegative(value)) + { + bits = ~bits + 1; + } + + actualResult = bits; + } + else + { + actualResult = (nuint)value._sign; + } + + result = (TOther)(object)actualResult; return true; } else { - ThrowHelper.ThrowNotSupportedException(); - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs index 9d67f3058e5f82..534605a6ac2c8f 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Numerics { @@ -799,35 +800,86 @@ private static Complex Scale(Complex value, double factor) return new Complex(realResult, imaginaryResuilt); } - public static implicit operator Complex(short value) + // + // Explicit Conversions To Complex + // + + public static explicit operator Complex(decimal value) + { + return new Complex((double)value, 0.0); + } + + /// Explicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + public static explicit operator Complex(Int128 value) + { + return new Complex((double)value, 0.0); + } + + public static explicit operator Complex(BigInteger value) + { + return new Complex((double)value, 0.0); + } + + /// Explicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + [CLSCompliant(false)] + public static explicit operator Complex(UInt128 value) + { + return new Complex((double)value, 0.0); + } + + // + // Implicit Conversions To Complex + // + + public static implicit operator Complex(byte value) { return new Complex(value, 0.0); } - public static implicit operator Complex(int value) + /// Implicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + public static implicit operator Complex(char value) { return new Complex(value, 0.0); } - public static implicit operator Complex(long value) + public static implicit operator Complex(double value) { return new Complex(value, 0.0); } - [CLSCompliant(false)] - public static implicit operator Complex(ushort value) + /// Implicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + public static implicit operator Complex(Half value) + { + return new Complex((double)value, 0.0); + } + + public static implicit operator Complex(short value) { return new Complex(value, 0.0); } - [CLSCompliant(false)] - public static implicit operator Complex(uint value) + public static implicit operator Complex(int value) { return new Complex(value, 0.0); } - [CLSCompliant(false)] - public static implicit operator Complex(ulong value) + public static implicit operator Complex(long value) + { + return new Complex(value, 0.0); + } + + /// Implicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + public static implicit operator Complex(nint value) { return new Complex(value, 0.0); } @@ -838,29 +890,36 @@ public static implicit operator Complex(sbyte value) return new Complex(value, 0.0); } - public static implicit operator Complex(byte value) + public static implicit operator Complex(float value) { return new Complex(value, 0.0); } - public static implicit operator Complex(float value) + [CLSCompliant(false)] + public static implicit operator Complex(ushort value) { return new Complex(value, 0.0); } - public static implicit operator Complex(double value) + [CLSCompliant(false)] + public static implicit operator Complex(uint value) { return new Complex(value, 0.0); } - public static explicit operator Complex(BigInteger value) + [CLSCompliant(false)] + public static implicit operator Complex(ulong value) { - return new Complex((double)value, 0.0); + return new Complex(value, 0.0); } - public static explicit operator Complex(decimal value) + /// Implicitly converts a value to a double-precision complex number. + /// The value to convert. + /// converted to a double-precision complex number. + [CLSCompliant(false)] + public static implicit operator Complex(nuint value) { - return new Complex((double)value, 0.0); + return new Complex(value, 0.0); } // @@ -934,210 +993,6 @@ public static explicit operator Complex(decimal value) /// static Complex INumberBase.Abs(Complex value) => Abs(value); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateChecked(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Complex)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateSaturating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Complex)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateTruncating(TOther value) - where TOther : INumberBase - { - if (typeof(TOther) == typeof(byte)) - { - return (byte)(object)value; - } - else if (typeof(TOther) == typeof(char)) - { - return (char)(object)value; - } - else if (typeof(TOther) == typeof(decimal)) - { - return (Complex)(decimal)(object)value; - } - else if (typeof(TOther) == typeof(double)) - { - return (double)(object)value; - } - else if (typeof(TOther) == typeof(short)) - { - return (short)(object)value; - } - else if (typeof(TOther) == typeof(int)) - { - return (int)(object)value; - } - else if (typeof(TOther) == typeof(long)) - { - return (long)(object)value; - } - else if (typeof(TOther) == typeof(nint)) - { - return (nint)(object)value; - } - else if (typeof(TOther) == typeof(sbyte)) - { - return (sbyte)(object)value; - } - else if (typeof(TOther) == typeof(float)) - { - return (float)(object)value; - } - else if (typeof(TOther) == typeof(ushort)) - { - return (ushort)(object)value; - } - else if (typeof(TOther) == typeof(uint)) - { - return (uint)(object)value; - } - else if (typeof(TOther) == typeof(ulong)) - { - return (ulong)(object)value; - } - else if (typeof(TOther) == typeof(nuint)) - { - return (nuint)(object)value; - } - else - { - ThrowHelper.ThrowNotSupportedException(); - return default; - } - } - /// static bool INumberBase.IsCanonical(Complex value) => true; @@ -1598,89 +1453,621 @@ public static Complex Parse(string s, NumberStyles style, IFormatProvider? provi return Parse(s.AsSpan(), style, provider); } - /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromChecked(TOther value, out Complex result) + { + return TryConvertFrom(value, out result); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertFromSaturating(TOther value, out Complex result) + { + return TryConvertFrom(value, out result); + } + + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate(TOther value, out Complex result) + static bool INumberBase.TryConvertFromTruncating(TOther value, out Complex result) + { + return TryConvertFrom(value, out result); + } + + private static bool TryConvertFrom(TOther value, out Complex result) where TOther : INumberBase { + // We don't want to defer to `double.Create*(value)` because some type might have its own + // `TOther.ConvertTo*(value, out Complex result)` handling that would end up bypassed. + if (typeof(TOther) == typeof(byte)) { - result = (byte)(object)value; + byte actualValue = (byte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(char)) { - result = (char)(object)value; + char actualValue = (char)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(decimal)) { - result = (Complex)(decimal)(object)value; + decimal actualValue = (decimal)(object)value; + result = (Complex)actualValue; return true; } else if (typeof(TOther) == typeof(double)) { - result = (double)(object)value; + double actualValue = (double)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualValue = (Half)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(short)) { - result = (short)(object)value; + short actualValue = (short)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(int)) { - result = (int)(object)value; + int actualValue = (int)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(long)) { - result = (long)(object)value; + long actualValue = (long)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualValue = (Int128)(object)value; + result = (Complex)actualValue; return true; } else if (typeof(TOther) == typeof(nint)) { - result = (nint)(object)value; + nint actualValue = (nint)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(sbyte)) { - result = (sbyte)(object)value; + sbyte actualValue = (sbyte)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(float)) { - result = (float)(object)value; + float actualValue = (float)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(ushort)) { - result = (ushort)(object)value; + ushort actualValue = (ushort)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(uint)) { - result = (uint)(object)value; + uint actualValue = (uint)(object)value; + result = actualValue; return true; } else if (typeof(TOther) == typeof(ulong)) { - result = (ulong)(object)value; + ulong actualValue = (ulong)(object)value; + result = actualValue; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualValue = (UInt128)(object)value; + result = (Complex)actualValue; return true; } else if (typeof(TOther) == typeof(nuint)) { - result = (nuint)(object)value; + nuint actualValue = (nuint)(object)value; + result = actualValue; return true; } else { - ThrowHelper.ThrowNotSupportedException(); result = default; return false; } } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToChecked(Complex value, [NotNullWhen(true)] out TOther result) + { + // Complex numbers with an imaginary part can't be represented as a "real number" + // so we'll throw an OverflowException for this scenario for integer types and + // for decimal. However, we will convert it to NaN for the floating-point types, + // since that's what Sqrt(-1) (which is `new Complex(0, 1)`) results in. + + if (typeof(TOther) == typeof(byte)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + byte actualResult = checked((byte)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + char actualResult = checked((char)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + decimal actualResult = checked((decimal)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualResult = (value.m_imaginary != 0) ? double.NaN : value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (value.m_imaginary != 0) ? Half.NaN : (Half)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + short actualResult = checked((short)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + int actualResult = checked((int)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + long actualResult = checked((long)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + Int128 actualResult = checked((Int128)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + nint actualResult = checked((nint)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(BigInteger)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + BigInteger actualResult = checked((BigInteger)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + sbyte actualResult = checked((sbyte)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (value.m_imaginary != 0) ? float.NaN : (float)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + ushort actualResult = checked((ushort)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + uint actualResult = checked((uint)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + ulong actualResult = checked((ulong)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + UInt128 actualResult = checked((UInt128)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + if (value.m_imaginary != 0) + { + ThrowHelper.ThrowOverflowException(); + } + + nuint actualResult = checked((nuint)value.m_real); + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToSaturating(Complex value, [NotNullWhen(true)] out TOther result) + { + // Complex numbers with an imaginary part can't be represented as a "real number" + // and there isn't really a well-defined way to "saturate" to just a real value. + // + // The two potential options are that we either treat complex numbers with a non- + // zero imaginary part as NaN and then convert that to 0 -or- we ignore the imaginary + // part and only consider the real part. + // + // We use the latter below since that is "more useful" given an unknown number type. + // Users who want 0 instead can always check `IsComplexNumber` and special-case the + // handling. + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value.m_real >= byte.MaxValue) ? byte.MaxValue : + (value.m_real <= byte.MinValue) ? byte.MinValue : (byte)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value.m_real >= char.MaxValue) ? char.MaxValue : + (value.m_real <= char.MinValue) ? char.MinValue : (char)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value.m_real >= (double)decimal.MaxValue) ? decimal.MaxValue : + (value.m_real <= (double)decimal.MinValue) ? decimal.MinValue : (decimal)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualResult = value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult = (value.m_real >= short.MaxValue) ? short.MaxValue : + (value.m_real <= short.MinValue) ? short.MinValue : (short)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualResult = (value.m_real >= int.MaxValue) ? int.MaxValue : + (value.m_real <= int.MinValue) ? int.MinValue : (int)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualResult = (value.m_real >= long.MaxValue) ? long.MaxValue : + (value.m_real <= long.MinValue) ? long.MinValue : (long)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = (value.m_real >= +170141183460469231731687303715884105727.0) ? Int128.MaxValue : + (value.m_real <= -170141183460469231731687303715884105728.0) ? Int128.MinValue : (Int128)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualResult = (value.m_real >= nint.MaxValue) ? nint.MaxValue : + (value.m_real <= nint.MinValue) ? nint.MinValue : (nint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(BigInteger)) + { + BigInteger actualResult = (BigInteger)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult = (value.m_real >= sbyte.MaxValue) ? sbyte.MaxValue : + (value.m_real <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value.m_real >= ushort.MaxValue) ? ushort.MaxValue : + (value.m_real <= ushort.MinValue) ? ushort.MinValue : (ushort)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value.m_real >= uint.MaxValue) ? uint.MaxValue : + (value.m_real <= uint.MinValue) ? uint.MinValue : (uint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value.m_real >= ulong.MaxValue) ? ulong.MaxValue : + (value.m_real <= ulong.MinValue) ? ulong.MinValue : (ulong)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value.m_real >= 340282366920938463463374607431768211455.0) ? UInt128.MaxValue : + (value.m_real <= 0.0) ? UInt128.MinValue : (UInt128)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (value.m_real >= nuint.MaxValue) ? nuint.MaxValue : + (value.m_real <= nuint.MinValue) ? nuint.MinValue : (nuint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase.TryConvertToTruncating(Complex value, [NotNullWhen(true)] out TOther result) + { + // Complex numbers with an imaginary part can't be represented as a "real number" + // so we'll only consider the real part for the purposes of truncation. + + if (typeof(TOther) == typeof(byte)) + { + byte actualResult = (value.m_real >= byte.MaxValue) ? byte.MaxValue : + (value.m_real <= byte.MinValue) ? byte.MinValue : (byte)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult = (value.m_real >= char.MaxValue) ? char.MaxValue : + (value.m_real <= char.MinValue) ? char.MinValue : (char)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(decimal)) + { + decimal actualResult = (value.m_real >= (double)decimal.MaxValue) ? decimal.MaxValue : + (value.m_real <= (double)decimal.MinValue) ? decimal.MinValue : (decimal)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(double)) + { + double actualResult = value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Half)) + { + Half actualResult = (Half)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(short)) + { + short actualResult = (value.m_real >= short.MaxValue) ? short.MaxValue : + (value.m_real <= short.MinValue) ? short.MinValue : (short)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(int)) + { + int actualResult = (value.m_real >= int.MaxValue) ? int.MaxValue : + (value.m_real <= int.MinValue) ? int.MinValue : (int)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(long)) + { + long actualResult = (value.m_real >= long.MaxValue) ? long.MaxValue : + (value.m_real <= long.MinValue) ? long.MinValue : (long)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(Int128)) + { + Int128 actualResult = (value.m_real >= +170141183460469231731687303715884105727.0) ? Int128.MaxValue : + (value.m_real <= -170141183460469231731687303715884105728.0) ? Int128.MinValue : (Int128)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nint)) + { + nint actualResult = (value.m_real >= nint.MaxValue) ? nint.MaxValue : + (value.m_real <= nint.MinValue) ? nint.MinValue : (nint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(BigInteger)) + { + BigInteger actualResult = (BigInteger)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult = (value.m_real >= sbyte.MaxValue) ? sbyte.MaxValue : + (value.m_real <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(float)) + { + float actualResult = (float)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ushort)) + { + ushort actualResult = (value.m_real >= ushort.MaxValue) ? ushort.MaxValue : + (value.m_real <= ushort.MinValue) ? ushort.MinValue : (ushort)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(uint)) + { + uint actualResult = (value.m_real >= uint.MaxValue) ? uint.MaxValue : + (value.m_real <= uint.MinValue) ? uint.MinValue : (uint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(ulong)) + { + ulong actualResult = (value.m_real >= ulong.MaxValue) ? ulong.MaxValue : + (value.m_real <= ulong.MinValue) ? ulong.MinValue : (ulong)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(UInt128)) + { + UInt128 actualResult = (value.m_real >= 340282366920938463463374607431768211455.0) ? UInt128.MaxValue : + (value.m_real <= 0.0) ? UInt128.MinValue : (UInt128)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(nuint)) + { + nuint actualResult = (value.m_real >= nuint.MaxValue) ? nuint.MaxValue : + (value.m_real <= nuint.MinValue) ? nuint.MinValue : (nuint)value.m_real; + result = (TOther)(object)actualResult; + return true; + } + else + { + result = default!; + return false; + } + } + /// public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out Complex result) { diff --git a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs index 889aa29edc337b..784c75ab9be75f 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Numerics.Tests @@ -1040,6 +1041,60 @@ public static void CreateCheckedFromCharTest() Assert.Equal(UInt16MaxValue, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper.CreateChecked(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper.CreateChecked(decimal.MinValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateChecked(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateChecked(-170141183460469212842221372237303250944.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateChecked((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -1070,6 +1125,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -1101,6 +1166,27 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateChecked(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateChecked(-170141173319264429905852091742258462720.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1131,6 +1217,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateChecked(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateChecked(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -1172,6 +1268,60 @@ public static void CreateSaturatingFromCharTest() Assert.Equal(UInt16MaxValue, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper.CreateSaturating(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateSaturating(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateSaturating(-170141183460469212842221372237303250944.0)); + + Assert.Throws(() => NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateSaturating((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -1202,6 +1352,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -1233,6 +1393,27 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateSaturating(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateSaturating(-170141173319264429905852091742258462720.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1263,6 +1444,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateSaturating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateSaturating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1304,6 +1495,60 @@ public static void CreateTruncatingFromCharTest() Assert.Equal(UInt16MaxValue, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper.CreateTruncating(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateTruncating(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateTruncating(-170141183460469212842221372237303250944.0)); + + Assert.Throws(() => NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateTruncating((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -1334,6 +1579,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -1365,6 +1620,27 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateTruncating(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper.CreateTruncating(-170141173319264429905852091742258462720.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1395,6 +1671,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateTruncating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1710,274 +1996,607 @@ public static void MinMagnitudeNumberTest() Assert.Equal(One, NumberBaseHelper.MinMagnitudeNumber(UInt64MaxValue, 1)); } + // + // INumberBase.TryConvertTo + // + [Fact] - public static void TryCreateFromByteTest() + public static void TryConvertToCheckedByteTest() { - BigInteger result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateChecked(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateChecked(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked(ByteMaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToCheckedCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateChecked(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateChecked(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); + [Fact] + public static void TryConvertToCheckedDecimalTest() + { + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateChecked(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); + Assert.Equal(decimal.One, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper.CreateChecked(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)))); } [Fact] - public static void TryCreateFromCharTest() + public static void TryConvertToCheckedDoubleTest() { - BigInteger result; + Assert.Equal(+0.0, NumberBaseHelper.CreateChecked(Zero)); - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(-1.0, NumberBaseHelper.CreateChecked(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(One, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToCheckedHalfTest() + { + Assert.Equal((Half)(+0.0), NumberBaseHelper.CreateChecked(Zero)); - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper.CreateChecked(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper.CreateChecked(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateChecked(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateChecked(-65504)); } [Fact] - public static void TryCreateFromInt16Test() + public static void TryConvertToCheckedInt16Test() { - BigInteger result; + Assert.Equal(0x0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(0x0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateChecked(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToCheckedInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper.CreateChecked(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateChecked(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToCheckedInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateChecked(Int64MaxValue)); + Assert.Equal(unchecked(unchecked((long)0x8000_0000_0000_0000)), NumberBaseHelper.CreateChecked(Int64MinValue)); + Assert.Equal(unchecked(unchecked((long)0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper.CreateChecked(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToCheckedInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(Int16MinValue, result); + [Fact] + public static void TryConvertToCheckedIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateChecked(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateChecked(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(NegativeOne)); + } + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToCheckedSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(0x01, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(0x7F, NumberBaseHelper.CreateChecked(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(NegativeOne)); } [Fact] - public static void TryCreateFromInt32Test() + public static void TryConvertToCheckedSingleTest() { - BigInteger result; + Assert.Equal(+0.0f, NumberBaseHelper.CreateChecked(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0f, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateChecked(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateChecked((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToCheckedUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateChecked(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateChecked(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); + [Fact] + public static void TryConvertToCheckedUInt32Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper.CreateChecked(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper.CreateChecked(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToCheckedUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateChecked(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper.CreateChecked(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateChecked(UInt64MaxValue)); } [Fact] - public static void TryCreateFromInt64Test() + public static void TryConvertToCheckedUInt128Test() { - BigInteger result; + Assert.Equal(UInt128.Zero, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper.CreateChecked(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper.CreateChecked(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToCheckedUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(One)); + Assert.Equal(unchecked((nuint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(One)); + Assert.Equal((nuint)0x7FFF_FFFF, NumberBaseHelper.CreateChecked(Int32MaxValue)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper.CreateChecked(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked(UInt32MaxValue)); + } + } - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateSaturating(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateSaturating(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(ByteMaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToSaturatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateSaturating(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateSaturating(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); + [Fact] + public static void TryConvertToSaturatingDecimalTest() + { + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateSaturating(Zero)); + + Assert.Equal(decimal.One, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper.CreateSaturating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)))); } [Fact] - public static void TryCreateFromIntPtrTest() + public static void TryConvertToSaturatingDoubleTest() { - BigInteger result; + Assert.Equal(+0.0, NumberBaseHelper.CreateSaturating(Zero)); - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x00000000), out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(-1.0, NumberBaseHelper.CreateSaturating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x00000001), out result)); - Assert.Equal(One, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToSaturatingHalfTest() + { + Assert.Equal((Half)(+0.0), NumberBaseHelper.CreateSaturating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper.CreateSaturating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateSaturating(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateSaturating(-65504)); + } - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(0x0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateSaturating(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(NegativeOne)); + } + + [Fact] + public static void TryConvertToSaturatingInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToSaturatingInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(Int64MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Int64MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); + [Fact] + public static void TryConvertToSaturatingInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToSaturatingIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateSaturating(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(NegativeOne)); } } [Fact] - public static void TryCreateFromSByteTest() + public static void TryConvertToSaturatingSByteTest() { - BigInteger result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); + Assert.Equal(0x00, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(0x01, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(0x7F, NumberBaseHelper.CreateSaturating(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingSingleTest() + { + Assert.Equal(+0.0f, NumberBaseHelper.CreateSaturating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); + Assert.Equal(+1.0f, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateSaturating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(SByteMinValue, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateSaturating((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToSaturatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateSaturating(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateSaturating(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(UInt16MaxValue)); } [Fact] - public static void TryCreateFromUInt16Test() + public static void TryConvertToSaturatingUInt32Test() { - BigInteger result; + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper.CreateSaturating(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToSaturatingUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt64MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingUInt128Test() + { + Assert.Equal(UInt128.Zero, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper.CreateSaturating(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToSaturatingUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(One)); + Assert.Equal(unchecked((nuint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(One)); + Assert.Equal((nuint)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(Int32MaxValue)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper.CreateSaturating(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt32MaxValue)); + } + } - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateTruncating(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateTruncating(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(ByteMaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); + [Fact] + public static void TryConvertToTruncatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateTruncating(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateTruncating(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(UInt16MaxValue)); } [Fact] - public static void TryCreateFromUInt32Test() + public static void TryConvertToTruncatingDecimalTest() { - BigInteger result; + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateTruncating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(decimal.One, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper.CreateTruncating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)))); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingDoubleTest() + { + Assert.Equal(+0.0, NumberBaseHelper.CreateTruncating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); + Assert.Equal(+1.0, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(-1.0, NumberBaseHelper.CreateTruncating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)))); } [Fact] - public static void TryCreateFromUInt64Test() + public static void TryConvertToTruncatingHalfTest() { - BigInteger result; + Assert.Equal((Half)(+0.0), NumberBaseHelper.CreateTruncating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper.CreateTruncating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateTruncating(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateTruncating(-65504)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToTruncatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(0x0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateTruncating(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper.CreateTruncating(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); + [Fact] + public static void TryConvertToTruncatingInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(Int64MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int64MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(NegativeOne)); } [Fact] - public static void TryCreateFromUIntPtrTest() + public static void TryConvertToTruncatingInt128Test() { - BigInteger result; + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] + public static void TryConvertToTruncatingIntPtrTest() + { if (Environment.Is64BitProcess) { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x00000000), out result)); - Assert.Equal(Zero, result); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(unchecked((nint)0x0000_0001), NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateTruncating(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateTruncating(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(NegativeOne)); + } + } + + [Fact] + public static void TryConvertToTruncatingSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(0x01, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(0x7F, NumberBaseHelper.CreateTruncating(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(NegativeOne)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x00000001), out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToTruncatingSingleTest() + { + Assert.Equal(+0.0f, NumberBaseHelper.CreateTruncating(Zero)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); + Assert.Equal(+1.0f, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateTruncating(NegativeOne)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper.CreateTruncating((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToTruncatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateTruncating(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateTruncating(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToTruncatingUInt32Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper.CreateTruncating(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper.CreateTruncating(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt64MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingUInt128Test() + { + Assert.Equal(UInt128.Zero, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper.CreateTruncating(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(UInt32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x00000000), NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal(unchecked((nuint)0x00000001), NumberBaseHelper.CreateTruncating(One)); + Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000000000000000), NumberBaseHelper.CreateTruncating(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateTruncating(Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateTruncating(One)); + Assert.Equal((nuint)0x7FFFFFFF, NumberBaseHelper.CreateTruncating(Int32MaxValue)); + Assert.Equal((nuint)0x80000000, NumberBaseHelper.CreateTruncating(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFFFFFF, NumberBaseHelper.CreateTruncating(UInt32MaxValue)); } } diff --git a/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs b/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs index 4425b15a9f04a9..06ceb1fc7a54b2 100644 --- a/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs +++ b/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.InteropServices; using Xunit; namespace System.Numerics.Tests @@ -309,6 +310,69 @@ public static void CreateCheckedFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateChecked(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper.CreateChecked(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper.CreateChecked(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateChecked(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper.CreateChecked(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper.CreateChecked(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateChecked(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateChecked(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateChecked(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateChecked(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -339,6 +403,16 @@ public static void CreateCheckedFromInt64Test() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateChecked(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateChecked(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateChecked(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper.CreateChecked(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -370,6 +444,32 @@ public static void CreateCheckedFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateChecked(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateChecked(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateChecked(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateChecked(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateChecked(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateChecked(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateChecked(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateChecked(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -400,6 +500,16 @@ public static void CreateCheckedFromUInt64Test() AssertBitwiseEqual(18446744073709551615.0, NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateChecked(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateChecked(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateChecked(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper.CreateChecked(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper.CreateChecked(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -445,6 +555,69 @@ public static void CreateSaturatingFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper.CreateSaturating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper.CreateSaturating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper.CreateSaturating(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper.CreateSaturating(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateSaturating(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateSaturating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateSaturating(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -475,6 +648,16 @@ public static void CreateSaturatingFromInt64Test() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateSaturating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateSaturating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateSaturating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper.CreateSaturating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -506,6 +689,32 @@ public static void CreateSaturatingFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateSaturating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -536,6 +745,16 @@ public static void CreateSaturatingFromUInt64Test() AssertBitwiseEqual(18446744073709551615.0, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateSaturating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateSaturating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateSaturating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper.CreateSaturating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper.CreateSaturating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -581,6 +800,69 @@ public static void CreateTruncatingFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper.CreateTruncating(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper.CreateTruncating(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper.CreateTruncating(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper.CreateTruncating(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateTruncating(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateTruncating(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateTruncating(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -611,6 +893,16 @@ public static void CreateTruncatingFromInt64Test() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateTruncating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateTruncating(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateTruncating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper.CreateTruncating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -642,6 +934,32 @@ public static void CreateTruncatingFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateTruncating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -672,6 +990,16 @@ public static void CreateTruncatingFromUInt64Test() AssertBitwiseEqual(18446744073709551615.0, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper.CreateTruncating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper.CreateTruncating(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper.CreateTruncating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper.CreateTruncating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1877,277 +2205,700 @@ public static void MinMagnitudeNumberTest() AssertBitwiseEqual(new Complex(+1.0, +1.0), NumberBaseHelper.MinMagnitudeNumber(new Complex(+1.0, +1.0), new Complex(+1.0, +1.0))); } + // + // INumberBase.TryConvertTo + // + + [Fact] + public static void TryConvertToCheckedByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateChecked(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateChecked(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked(255.0)); + } + + [Fact] + public static void TryConvertToCheckedCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateChecked(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateChecked(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked(65535.0)); + } + + [Fact] + public static void TryConvertToCheckedDecimalTest() + { + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper.CreateChecked(-79228162514264333195497439231.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateChecked(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper.CreateChecked(+79228162514264333195497439231.0)); + } + [Fact] - public static void TryCreateFromByteTest() + public static void TryConvertToCheckedDoubleTest() { - Complex result; + Assert.Equal(double.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Equal(-1.0, NumberBaseHelper.CreateChecked(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper.CreateChecked(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper.CreateChecked(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper.CreateChecked(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper.CreateChecked(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper.CreateChecked(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0, result); + Assert.Equal(1.0, NumberBaseHelper.CreateChecked(+1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(128.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(255.0, result); + Assert.Equal(double.NaN, NumberBaseHelper.CreateChecked(double.NaN)); } [Fact] - public static void TryCreateFromCharTest() + public static void TryConvertToCheckedHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateChecked(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateChecked(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateChecked(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper.CreateChecked(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal(Half.Zero, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper.CreateChecked(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateChecked(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateChecked(+6.103515625E-05)); - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.One, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateChecked(+65504.0)); + + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + Assert.Equal(Half.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + } + + [Fact] + public static void TryConvertToCheckedInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(0x0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateChecked(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(-1.0)); + } + + [Fact] + public static void TryConvertToCheckedInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper.CreateChecked(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper.CreateChecked(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateChecked(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToCheckedInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateChecked(+9223372036854774784.0)); + Assert.Equal(unchecked(unchecked((long)0x8000_0000_0000_0000)), NumberBaseHelper.CreateChecked(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper.CreateChecked(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(32767.0, result); + [Fact] + public static void TryConvertToCheckedInt128Test() + { + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(+170141183460469212842221372237303250944.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(32768.0, result); + [Fact] + public static void TryConvertToCheckedIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateChecked(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + } + else + { + Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper.CreateChecked(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper.CreateChecked(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper.CreateChecked(-1.0)); + } + } - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(65535.0, result); + [Fact] + public static void TryConvertToCheckedSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(0x01, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(0x7F, NumberBaseHelper.CreateChecked(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(-1.0)); } [Fact] - public static void TryCreateFromInt16Test() + public static void TryConvertToCheckedSingleTest() { - Complex result; + Assert.Equal(float.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Equal(float.MinValue, NumberBaseHelper.CreateChecked(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateChecked(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.17549435E-38f, NumberBaseHelper.CreateChecked(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper.CreateChecked(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper.CreateChecked(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper.CreateChecked(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0f, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper.CreateChecked(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper.CreateChecked(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper.CreateChecked(+1.1754943508222875E-38)); - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0, result); + Assert.Equal(1.0f, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper.CreateChecked(+3.4028234663852886E+38)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0, result); + Assert.Equal(float.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(float.NaN, NumberBaseHelper.CreateChecked(float.NaN)); } [Fact] - public static void TryCreateFromInt32Test() + public static void TryConvertToCheckedUInt16Test() { - Complex result; + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateChecked(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateChecked(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked(65535.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToCheckedUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper.CreateChecked(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper.CreateChecked(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateChecked(4294967295.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToCheckedUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper.CreateChecked(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateChecked(18446744073709549568.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + [Fact] + public static void TryConvertToCheckedUInt128Test() + { + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(340282366920938425684442744474606501888.0)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void TryConvertToCheckedUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(9223372036854775808.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateChecked(18446744073709549568.0)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(0.0)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(1.0)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper.CreateChecked(2147483648.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked(4294967295.0)); + } + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); + [Fact] + public static void TryConvertToSaturatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateSaturating(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateSaturating(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(255.0)); + } + + [Fact] + public static void TryConvertToSaturatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateSaturating(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateSaturating(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(65535.0)); + } + + [Fact] + public static void TryConvertToSaturatingDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(-79228162514264337593543950335.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateSaturating(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(+79228162514264337593543950335.0)); } [Fact] - public static void TryCreateFromInt64Test() + public static void TryConvertToSaturatingDoubleTest() { - Complex result; + Assert.Equal(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.0, NumberBaseHelper.CreateSaturating(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper.CreateSaturating(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper.CreateSaturating(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper.CreateSaturating(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(+0.0, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper.CreateSaturating(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper.CreateSaturating(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0, result); + Assert.Equal(1.0, NumberBaseHelper.CreateSaturating(+1.0)); - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + Assert.Equal(double.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); } [Fact] - public static void TryCreateFromIntPtrTest() + public static void TryConvertToSaturatingHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateSaturating(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper.CreateSaturating(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateSaturating(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateSaturating(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper.CreateSaturating(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper.CreateSaturating(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(Half.Zero, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper.CreateSaturating(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateSaturating(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateSaturating(+6.103515625E-05)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0, result); + Assert.Equal(Half.One, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateSaturating(+65504.0)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + Assert.Equal(Half.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + + [Fact] + public static void TryConvertToSaturatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(0x0001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateSaturating(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToSaturatingInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper.CreateSaturating(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper.CreateSaturating(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateSaturating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + [Fact] + public static void TryConvertToSaturatingInt64Test() + { + Assert.Equal(0x0000000000000000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(0x0000000000000001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(0x7FFFFFFFFFFFFFFF, NumberBaseHelper.CreateSaturating(9223372036854775807.0)); + Assert.Equal(unchecked(unchecked((long)0x8000000000000000)), NumberBaseHelper.CreateSaturating(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), NumberBaseHelper.CreateSaturating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); + [Fact] + public static void TryConvertToSaturatingInt128Test() + { + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(170141183460469231731687303715884105727.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); + [Fact] + public static void TryConvertToSaturatingIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000000000000000), NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(unchecked((nint)0x0000000000000001), NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper.CreateSaturating(9223372036854775807.0)); + Assert.Equal(unchecked((nint)0x8000000000000000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateSaturating(-1.0)); + } + else + { + Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper.CreateSaturating(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper.CreateSaturating(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper.CreateSaturating(-1.0)); } } [Fact] - public static void TryCreateFromSByteTest() + public static void TryConvertToSaturatingSByteTest() { - Complex result; + Assert.Equal(0x00, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(0x01, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(0x7F, NumberBaseHelper.CreateSaturating(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(-1.0)); + } + + [Fact] + public static void TryConvertToSaturatingSingleTest() + { + Assert.Equal(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal(float.MinValue, NumberBaseHelper.CreateSaturating(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateSaturating(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.17549435E-38f, NumberBaseHelper.CreateSaturating(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper.CreateSaturating(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper.CreateSaturating(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper.CreateSaturating(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0f, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper.CreateSaturating(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper.CreateSaturating(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper.CreateSaturating(+1.1754943508222875E-38)); - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0, result); + Assert.Equal(1.0f, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper.CreateSaturating(+3.4028234663852886E+38)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0, result); + Assert.Equal(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(float.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); } [Fact] - public static void TryCreateFromUInt16Test() + public static void TryConvertToSaturatingUInt16Test() { - Complex result; + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateSaturating(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateSaturating(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(65535.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToSaturatingUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper.CreateSaturating(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper.CreateSaturating(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateSaturating(4294967295.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToSaturatingUInt64Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal((ulong)0x8000000000000000, NumberBaseHelper.CreateSaturating(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateSaturating(18446744073709551615.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0, result); + [Fact] + public static void TryConvertToSaturatingUInt128Test() + { + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(340282366920938463463374607431768211455.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(32768.0, result); + [Fact] + public static void TryConvertToSaturatingUIntPtrTest() + { + // if (Environment.Is64BitProcess) + // { + // Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(0.0)); + // Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(1.0)); + // Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(9223372036854775808.0)); + // Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(18446744073709551615.0)); + // } + // else + // { + // Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(0.0)); + // Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(1.0)); + // Assert.Equal((nuint)0x8000_0000, NumberBaseHelper.CreateSaturating(2147483648.0)); + // Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(4294967295.0)); + // } + } - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(65535.0, result); + [Fact] + public static void TryConvertToTruncatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper.CreateTruncating(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper.CreateTruncating(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(255.0)); } [Fact] - public static void TryCreateFromUInt32Test() + public static void TryConvertToTruncatingCharTest() { - Complex result; + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper.CreateTruncating(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper.CreateTruncating(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(65535.0)); + } + + [Fact] + public static void TryConvertToTruncatingDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(-79228162514264337593543950335.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateTruncating(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(+79228162514264337593543950335.0)); + } - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToTruncatingDoubleTest() + { + Assert.Equal(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(-1.0, NumberBaseHelper.CreateTruncating(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper.CreateTruncating(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper.CreateTruncating(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper.CreateTruncating(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + Assert.Equal(+0.0, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper.CreateTruncating(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper.CreateTruncating(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(2147483648.0, result); + Assert.Equal(1.0, NumberBaseHelper.CreateTruncating(+1.0)); - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + Assert.Equal(double.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); } [Fact] - public static void TryCreateFromUInt64Test() + public static void TryConvertToTruncatingHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal(Half.MinValue, NumberBaseHelper.CreateTruncating(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper.CreateTruncating(-1.0)); - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateTruncating(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateTruncating(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper.CreateTruncating(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper.CreateTruncating(-0.0)); - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(Half.Zero, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper.CreateTruncating(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper.CreateTruncating(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper.CreateTruncating(+6.103515625E-05)); - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(Half.One, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper.CreateTruncating(+65504.0)); - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0, result); + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0, result); + Assert.Equal(Half.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); } [Fact] - public static void TryCreateFromUIntPtrTest() + public static void TryConvertToTruncatingInt16Test() { - Complex result; + Assert.Equal(0x0000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(0x0001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper.CreateTruncating(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(-1.0)); + } - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToTruncatingInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper.CreateTruncating(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper.CreateTruncating(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateTruncating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToTruncatingInt64Test() + { + Assert.Equal(0x0000000000000000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(0x0000000000000001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(unchecked(unchecked((long)0x8000000000000000)), NumberBaseHelper.CreateTruncating(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), NumberBaseHelper.CreateTruncating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); + [Fact] + public static void TryConvertToTruncatingInt128Test() + { + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(170141183460469231731687303715884105727.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0)); + } - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0, result); + [Fact] + public static void TryConvertToTruncatingIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000000000000000), NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(unchecked((nint)0x0000000000000001), NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(9223372036854775807.0)); + Assert.Equal(unchecked((nint)0x8000000000000000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(-1.0)); } else { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper.CreateTruncating(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper.CreateTruncating(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper.CreateTruncating(-1.0)); + } + } - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToTruncatingSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(0x01, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(0x7F, NumberBaseHelper.CreateTruncating(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(-1.0)); + } - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + [Fact] + public static void TryConvertToTruncatingSingleTest() + { + Assert.Equal(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal(4294967295.0, result); - } + Assert.Equal(float.MinValue, NumberBaseHelper.CreateTruncating(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal(-1.17549435E-38f, NumberBaseHelper.CreateTruncating(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper.CreateTruncating(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper.CreateTruncating(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal(+0.0f, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper.CreateTruncating(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper.CreateTruncating(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper.CreateTruncating(+1.1754943508222875E-38)); + + Assert.Equal(1.0f, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper.CreateTruncating(+3.4028234663852886E+38)); + + Assert.Equal(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + Assert.Equal(float.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + + [Fact] + public static void TryConvertToTruncatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper.CreateTruncating(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper.CreateTruncating(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(65535.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper.CreateTruncating(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper.CreateTruncating(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateTruncating(4294967295.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt64Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal((ulong)0x8000000000000000, NumberBaseHelper.CreateTruncating(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateTruncating(18446744073709551615.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt128Test() + { + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(340282366920938463463374607431768211455.0)); } // diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 490adf5a78537f..3203e3944878d5 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -728,9 +728,6 @@ public static void SetByte(System.Array array, int index, byte value) { } public static byte Clamp(byte value, byte min, byte max) { throw null; } public int CompareTo(byte value) { throw null; } public int CompareTo(object? value) { throw null; } - public static byte CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static byte CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static byte CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (byte Quotient, byte Remainder) DivRem(byte left, byte right) { throw null; } public bool Equals(byte obj) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -813,6 +810,12 @@ public static void SetByte(System.Array array, int index, byte value) { } static byte System.Numerics.INumberBase.MaxMagnitudeNumber(byte x, byte y) { throw null; } static byte System.Numerics.INumberBase.MinMagnitude(byte x, byte y) { throw null; } static byte System.Numerics.INumberBase.MinMagnitudeNumber(byte x, byte y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static byte System.Numerics.INumber.CopySign(byte value, byte sign) { throw null; } static byte System.Numerics.INumber.MaxNumber(byte x, byte y) { throw null; } static byte System.Numerics.INumber.MinNumber(byte x, byte y) { throw null; } @@ -829,7 +832,6 @@ public static void SetByte(System.Array array, int index, byte value) { } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static byte TrailingZeroCount(byte value) { throw null; } - public static bool TryCreate(TOther value, out byte result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, out byte result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out byte result) { throw null; } @@ -966,9 +968,6 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx static char System.Numerics.IMultiplyOperators.operator checked *(char left, char right) { throw null; } static char System.Numerics.IMultiplyOperators.operator *(char left, char right) { throw null; } static char System.Numerics.INumberBase.Abs(char value) { throw null; } - static char System.Numerics.INumberBase.CreateChecked(TOther value) { throw null; } - static char System.Numerics.INumberBase.CreateSaturating(TOther value) { throw null; } - static char System.Numerics.INumberBase.CreateTruncating(TOther value) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(char value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(char value) { throw null; } static bool System.Numerics.INumberBase.IsEvenInteger(char value) { throw null; } @@ -992,7 +991,12 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx static char System.Numerics.INumberBase.MinMagnitudeNumber(char x, char y) { throw null; } static char System.Numerics.INumberBase.Parse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } static char System.Numerics.INumberBase.Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } - static bool System.Numerics.INumberBase.TryCreate(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out char result) { throw null; } static bool System.Numerics.INumberBase.TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out char result) { throw null; } static char System.Numerics.INumber.Clamp(char value, char min, char max) { throw null; } @@ -1888,9 +1892,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S public int CompareTo(decimal value) { throw null; } public int CompareTo(object? value) { throw null; } public static decimal CopySign(decimal value, decimal sign) { throw null; } - public static decimal CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static decimal CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static decimal CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static decimal Divide(decimal d1, decimal d2) { throw null; } public bool Equals(decimal value) { throw null; } public static bool Equals(decimal d1, decimal d2) { throw null; } @@ -2012,6 +2013,12 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S static bool System.Numerics.INumberBase.IsZero(decimal value) { throw null; } static decimal System.Numerics.INumberBase.MaxMagnitudeNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.INumberBase.MinMagnitudeNumber(decimal x, decimal y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static decimal System.Numerics.INumber.MaxNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.INumber.MinNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.ISubtractionOperators.operator checked -(decimal left, decimal right) { throw null; } @@ -2038,7 +2045,6 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser [System.CLSCompliantAttribute(false)] public static ulong ToUInt64(decimal d) { throw null; } public static decimal Truncate(decimal d) { throw null; } - public static bool TryCreate(TOther value, out decimal result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryGetBits(decimal d, System.Span destination, out int valuesWritten) { throw null; } public static bool TryParse(System.ReadOnlySpan s, out decimal result) { throw null; } @@ -2141,9 +2147,6 @@ public DivideByZeroException(string? message, System.Exception? innerException) public static double CopySign(double x, double y) { throw null; } public static double Cos(double x) { throw null; } public static double Cosh(double x) { throw null; } - public static double CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static double CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static double CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public bool Equals(double obj) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public static double Exp(double x) { throw null; } @@ -2254,6 +2257,12 @@ public DivideByZeroException(string? message, System.Exception? innerException) static bool System.Numerics.INumberBase.IsComplexNumber(double value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(double value) { throw null; } static bool System.Numerics.INumberBase.IsZero(double value) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static double System.Numerics.ISubtractionOperators.operator checked -(double left, double right) { throw null; } static double System.Numerics.ISubtractionOperators.operator -(double left, double right) { throw null; } static double System.Numerics.IUnaryNegationOperators.operator checked -(double value) { throw null; } @@ -2266,7 +2275,6 @@ public DivideByZeroException(string? message, System.Exception? innerException) public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static double Truncate(double x) { throw null; } - public static bool TryCreate(TOther value, out double result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, out double result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out double result) { throw null; } @@ -2736,7 +2744,6 @@ public GopherStyleUriParser() { } public static System.Half PositiveInfinity { get { throw null; } } static System.Half System.Numerics.IAdditiveIdentity.AdditiveIdentity { get { throw null; } } static int System.Numerics.INumberBase.Radix { get { throw null; } } - static System.Half System.Numerics.ISignedNumber.NegativeOne { get { throw null; } } public static System.Half Tau { get { throw null; } } public static System.Half Zero { get { throw null; } } public static System.Half Abs(System.Half value) { throw null; } @@ -2757,9 +2764,6 @@ public GopherStyleUriParser() { } public static System.Half CopySign(System.Half x, System.Half y) { throw null; } public static System.Half Cos(System.Half x) { throw null; } public static System.Half Cosh(System.Half x) { throw null; } - public static System.Half CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Half CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Half CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public bool Equals(System.Half other) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public static System.Half Exp(System.Half x) { throw null; } @@ -2803,15 +2807,71 @@ public GopherStyleUriParser() { } public static System.Half MinMagnitudeNumber(System.Half x, System.Half y) { throw null; } public static System.Half MinNumber(System.Half x, System.Half y) { throw null; } public static System.Half operator +(System.Half left, System.Half right) { throw null; } + public static explicit operator checked byte (System.Half value) { throw null; } + public static explicit operator checked char (System.Half value) { throw null; } + public static explicit operator checked short (System.Half value) { throw null; } + public static explicit operator checked int (System.Half value) { throw null; } + public static explicit operator checked long (System.Half value) { throw null; } + public static explicit operator checked System.Int128 (System.Half value) { throw null; } + public static explicit operator checked nint (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked sbyte (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked ushort (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked uint (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked ulong (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked System.UInt128 (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator checked nuint (System.Half value) { throw null; } public static System.Half operator --(System.Half value) { throw null; } public static System.Half operator /(System.Half left, System.Half right) { throw null; } public static bool operator ==(System.Half left, System.Half right) { throw null; } + public static explicit operator System.Half (char value) { throw null; } + public static explicit operator System.Half (decimal value) { throw null; } public static explicit operator System.Half (double value) { throw null; } + public static explicit operator byte (System.Half value) { throw null; } + public static explicit operator char (System.Half value) { throw null; } + public static explicit operator decimal (System.Half value) { throw null; } public static explicit operator double (System.Half value) { throw null; } + public static explicit operator System.Int128 (System.Half value) { throw null; } + public static explicit operator short (System.Half value) { throw null; } + public static explicit operator int (System.Half value) { throw null; } + public static explicit operator long (System.Half value) { throw null; } + public static explicit operator nint (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator sbyte (System.Half value) { throw null; } public static explicit operator float (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.UInt128 (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator ushort (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator uint (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator ulong (System.Half value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator nuint (System.Half value) { throw null; } + public static explicit operator System.Half (short value) { throw null; } + public static explicit operator System.Half (int value) { throw null; } + public static explicit operator System.Half (long value) { throw null; } + public static explicit operator System.Half (nint value) { throw null; } public static explicit operator System.Half (float value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Half (ushort value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Half (uint value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Half (ulong value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static explicit operator System.Half (nuint value) { throw null; } public static bool operator >(System.Half left, System.Half right) { throw null; } public static bool operator >=(System.Half left, System.Half right) { throw null; } + public static implicit operator System.Half (byte value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static implicit operator System.Half (sbyte value) { throw null; } public static System.Half operator ++(System.Half value) { throw null; } public static bool operator !=(System.Half left, System.Half right) { throw null; } public static bool operator <(System.Half left, System.Half right) { throw null; } @@ -2861,6 +2921,12 @@ public GopherStyleUriParser() { } static bool System.Numerics.INumberBase.IsComplexNumber(System.Half value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(System.Half value) { throw null; } static bool System.Numerics.INumberBase.IsZero(System.Half value) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Half System.Numerics.ISubtractionOperators.operator checked -(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IUnaryNegationOperators.operator checked -(System.Half value) { throw null; } public static System.Half Tan(System.Half x) { throw null; } @@ -2870,7 +2936,6 @@ public GopherStyleUriParser() { } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static System.Half Truncate(System.Half x) { throw null; } - public static bool TryCreate(TOther value, out System.Half result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Half result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, out System.Half result) { throw null; } @@ -3022,9 +3087,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public int CompareTo(System.Int128 value) { throw null; } public int CompareTo(object? value) { throw null; } public static System.Int128 CopySign(System.Int128 value, System.Int128 sign) { throw null; } - public static System.Int128 CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Int128 CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.Int128 CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (System.Int128 Quotient, System.Int128 Remainder) DivRem(System.Int128 left, System.Int128 right) { throw null; } public bool Equals(System.Int128 other) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -3047,7 +3109,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public static System.Int128 operator checked --(System.Int128 value) { throw null; } public static System.Int128 operator checked /(System.Int128 left, System.Int128 right) { throw null; } public static explicit operator checked System.Int128 (double value) { throw null; } - public static explicit operator checked System.Int128 (System.Half value) { throw null; } public static explicit operator checked byte (System.Int128 value) { throw null; } public static explicit operator checked char (System.Int128 value) { throw null; } public static explicit operator checked short (System.Int128 value) { throw null; } @@ -3066,7 +3127,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public static explicit operator checked System.UInt128 (System.Int128 value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator checked nuint (System.Int128 value) { throw null; } - public static explicit operator checked System.Int128 (float value) { throw null; } + public static explicit operator checked System.Int128(float value) { throw null; } public static System.Int128 operator checked ++(System.Int128 value) { throw null; } public static System.Int128 operator checked *(System.Int128 left, System.Int128 right) { throw null; } public static System.Int128 operator checked -(System.Int128 left, System.Int128 right) { throw null; } @@ -3077,7 +3138,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public static System.Int128 operator ^(System.Int128 left, System.Int128 right) { throw null; } public static explicit operator System.Int128 (decimal value) { throw null; } public static explicit operator System.Int128 (double value) { throw null; } - public static explicit operator System.Int128 (System.Half value) { throw null; } public static explicit operator byte (System.Int128 value) { throw null; } public static explicit operator char (System.Int128 value) { throw null; } public static explicit operator decimal (System.Int128 value) { throw null; } @@ -3161,6 +3221,12 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.INumberBase.IsZero(System.Int128 value) { throw null; } static System.Int128 System.Numerics.INumberBase.MaxMagnitudeNumber(System.Int128 x, System.Int128 y) { throw null; } static System.Int128 System.Numerics.INumberBase.MinMagnitudeNumber(System.Int128 x, System.Int128 y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Int128 System.Numerics.INumber.MaxNumber(System.Int128 x, System.Int128 y) { throw null; } static System.Int128 System.Numerics.INumber.MinNumber(System.Int128 x, System.Int128 y) { throw null; } public override string ToString() { throw null; } @@ -3168,7 +3234,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static System.Int128 TrailingZeroCount(System.Int128 value) { throw null; } - public static bool TryCreate(TOther value, out System.Int128 result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Int128 result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.Int128 result) { throw null; } @@ -3195,9 +3260,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public int CompareTo(short value) { throw null; } public int CompareTo(object? value) { throw null; } public static short CopySign(short value, short sign) { throw null; } - public static short CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static short CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static short CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (short Quotient, short Remainder) DivRem(short left, short right) { throw null; } public bool Equals(short obj) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -3279,6 +3341,12 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.INumberBase.IsZero(short value) { throw null; } static short System.Numerics.INumberBase.MaxMagnitudeNumber(short x, short y) { throw null; } static short System.Numerics.INumberBase.MinMagnitudeNumber(short x, short y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static short System.Numerics.INumber.MaxNumber(short x, short y) { throw null; } static short System.Numerics.INumber.MinNumber(short x, short y) { throw null; } static short System.Numerics.IShiftOperators.operator <<(short value, int shiftAmount) { throw null; } @@ -3294,7 +3362,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static short TrailingZeroCount(short value) { throw null; } - public static bool TryCreate(TOther value, out short result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out short result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out short result) { throw null; } @@ -3321,9 +3388,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public int CompareTo(int value) { throw null; } public int CompareTo(object? value) { throw null; } public static int CopySign(int value, int sign) { throw null; } - public static int CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static int CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static int CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (int Quotient, int Remainder) DivRem(int left, int right) { throw null; } public bool Equals(int obj) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -3405,6 +3469,12 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.INumberBase.IsZero(int value) { throw null; } static int System.Numerics.INumberBase.MaxMagnitudeNumber(int x, int y) { throw null; } static int System.Numerics.INumberBase.MinMagnitudeNumber(int x, int y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static int System.Numerics.INumber.MaxNumber(int x, int y) { throw null; } static int System.Numerics.INumber.MinNumber(int x, int y) { throw null; } static int System.Numerics.IShiftOperators.operator <<(int value, int shiftAmount) { throw null; } @@ -3420,7 +3490,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static int TrailingZeroCount(int value) { throw null; } - public static bool TryCreate(TOther value, out int result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out int result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out int result) { throw null; } @@ -3447,9 +3516,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public int CompareTo(long value) { throw null; } public int CompareTo(object? value) { throw null; } public static long CopySign(long value, long sign) { throw null; } - public static long CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static long CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static long CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (long Quotient, long Remainder) DivRem(long left, long right) { throw null; } public bool Equals(long obj) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -3531,6 +3597,12 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.INumberBase.IsZero(long value) { throw null; } static long System.Numerics.INumberBase.MaxMagnitudeNumber(long x, long y) { throw null; } static long System.Numerics.INumberBase.MinMagnitudeNumber(long x, long y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static long System.Numerics.INumber.MaxNumber(long x, long y) { throw null; } static long System.Numerics.INumber.MinNumber(long x, long y) { throw null; } static long System.Numerics.IShiftOperators.operator <<(long value, int shiftAmount) { throw null; } @@ -3546,7 +3618,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static long TrailingZeroCount(long value) { throw null; } - public static bool TryCreate(TOther value, out long result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out long result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out long result) { throw null; } @@ -3580,9 +3651,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public int CompareTo(nint value) { throw null; } public int CompareTo(object? value) { throw null; } public static nint CopySign(nint value, nint sign) { throw null; } - public static nint CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static nint CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static nint CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (nint Quotient, nint Remainder) DivRem(nint left, nint right) { throw null; } public bool Equals(nint other) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -3659,6 +3727,12 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.INumberBase.IsZero(nint value) { throw null; } static nint System.Numerics.INumberBase.MaxMagnitudeNumber(nint x, nint y) { throw null; } static nint System.Numerics.INumberBase.MinMagnitudeNumber(nint x, nint y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static nint System.Numerics.INumber.MaxNumber(nint x, nint y) { throw null; } static nint System.Numerics.INumber.MinNumber(nint x, nint y) { throw null; } static nint System.Numerics.IShiftOperators.operator <<(nint value, int shiftAmount) { throw null; } @@ -3679,7 +3753,6 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static nint TrailingZeroCount(nint value) { throw null; } - public static bool TryCreate(TOther value, out nint result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out nint result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out nint result) { throw null; } @@ -4511,9 +4584,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S public int CompareTo(object? obj) { throw null; } public int CompareTo(sbyte value) { throw null; } public static sbyte CopySign(sbyte value, sbyte sign) { throw null; } - public static sbyte CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static sbyte CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static sbyte CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (sbyte Quotient, sbyte Remainder) DivRem(sbyte left, sbyte right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(sbyte obj) { throw null; } @@ -4595,6 +4665,12 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S static bool System.Numerics.INumberBase.IsZero(sbyte value) { throw null; } static sbyte System.Numerics.INumberBase.MaxMagnitudeNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.INumberBase.MinMagnitudeNumber(sbyte x, sbyte y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static sbyte System.Numerics.INumber.MaxNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.INumber.MinNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.IShiftOperators.operator <<(sbyte value, int shiftAmount) { throw null; } @@ -4610,7 +4686,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static sbyte TrailingZeroCount(sbyte value) { throw null; } - public static bool TryCreate(TOther value, out sbyte result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out sbyte result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out sbyte result) { throw null; } @@ -4671,9 +4746,6 @@ public SerializableAttribute() { } public static float CopySign(float x, float y) { throw null; } public static float Cos(float x) { throw null; } public static float Cosh(float x) { throw null; } - public static float CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static float CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static float CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(float obj) { throw null; } public static float Exp(float x) { throw null; } @@ -4784,6 +4856,12 @@ public SerializableAttribute() { } static bool System.Numerics.INumberBase.IsComplexNumber(float value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(float value) { throw null; } static bool System.Numerics.INumberBase.IsZero(float value) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static float System.Numerics.ISubtractionOperators.operator checked -(float left, float right) { throw null; } static float System.Numerics.ISubtractionOperators.operator -(float left, float right) { throw null; } static float System.Numerics.IUnaryNegationOperators.operator checked -(float value) { throw null; } @@ -4796,7 +4874,6 @@ public SerializableAttribute() { } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static float Truncate(float x) { throw null; } - public static bool TryCreate(TOther value, out float result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out float result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out float result) { throw null; } @@ -5988,9 +6065,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static System.UInt128 Clamp(System.UInt128 value, System.UInt128 min, System.UInt128 max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(System.UInt128 value) { throw null; } - public static System.UInt128 CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.UInt128 CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static System.UInt128 CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (System.UInt128 Quotient, System.UInt128 Remainder) DivRem(System.UInt128 left, System.UInt128 right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.UInt128 other) { throw null; } @@ -6009,7 +6083,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static System.UInt128 operator checked --(System.UInt128 value) { throw null; } public static System.UInt128 operator checked /(System.UInt128 left, System.UInt128 right) { throw null; } public static explicit operator checked System.UInt128 (double value) { throw null; } - public static explicit operator checked System.UInt128 (System.Half value) { throw null; } public static explicit operator checked System.UInt128 (short value) { throw null; } public static explicit operator checked System.UInt128 (int value) { throw null; } public static explicit operator checked System.UInt128 (long value) { throw null; } @@ -6045,7 +6118,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static System.UInt128 operator ^(System.UInt128 left, System.UInt128 right) { throw null; } public static explicit operator System.UInt128 (decimal value) { throw null; } public static explicit operator System.UInt128 (double value) { throw null; } - public static explicit operator System.UInt128 (System.Half value) { throw null; } public static explicit operator System.UInt128 (short value) { throw null; } public static explicit operator System.UInt128 (int value) { throw null; } public static explicit operator System.UInt128 (long value) { throw null; } @@ -6134,6 +6206,12 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static System.UInt128 System.Numerics.INumberBase.MaxMagnitudeNumber(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumberBase.MinMagnitude(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumberBase.MinMagnitudeNumber(System.UInt128 x, System.UInt128 y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.UInt128 System.Numerics.INumber.CopySign(System.UInt128 value, System.UInt128 sign) { throw null; } static System.UInt128 System.Numerics.INumber.MaxNumber(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumber.MinNumber(System.UInt128 x, System.UInt128 y) { throw null; } @@ -6142,7 +6220,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static System.UInt128 TrailingZeroCount(System.UInt128 value) { throw null; } - public static bool TryCreate(TOther value, out System.UInt128 result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.UInt128 result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.UInt128 result) { throw null; } @@ -6167,9 +6244,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static ushort Clamp(ushort value, ushort min, ushort max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(ushort value) { throw null; } - public static ushort CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static ushort CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static ushort CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (ushort Quotient, ushort Remainder) DivRem(ushort left, ushort right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(ushort obj) { throw null; } @@ -6252,6 +6326,12 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static ushort System.Numerics.INumberBase.MaxMagnitudeNumber(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumberBase.MinMagnitude(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumberBase.MinMagnitudeNumber(ushort x, ushort y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static ushort System.Numerics.INumber.CopySign(ushort value, ushort sign) { throw null; } static ushort System.Numerics.INumber.MaxNumber(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumber.MinNumber(ushort x, ushort y) { throw null; } @@ -6268,7 +6348,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static ushort TrailingZeroCount(ushort value) { throw null; } - public static bool TryCreate(TOther value, out ushort result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out ushort result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out ushort result) { throw null; } @@ -6293,9 +6372,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static uint Clamp(uint value, uint min, uint max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(uint value) { throw null; } - public static uint CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static uint CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static uint CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (uint Quotient, uint Remainder) DivRem(uint left, uint right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(uint obj) { throw null; } @@ -6378,6 +6454,12 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static uint System.Numerics.INumberBase.MaxMagnitudeNumber(uint x, uint y) { throw null; } static uint System.Numerics.INumberBase.MinMagnitude(uint x, uint y) { throw null; } static uint System.Numerics.INumberBase.MinMagnitudeNumber(uint x, uint y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static uint System.Numerics.INumber.CopySign(uint value, uint sign) { throw null; } static uint System.Numerics.INumber.MaxNumber(uint x, uint y) { throw null; } static uint System.Numerics.INumber.MinNumber(uint x, uint y) { throw null; } @@ -6394,7 +6476,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static uint TrailingZeroCount(uint value) { throw null; } - public static bool TryCreate(TOther value, out uint result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out uint result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out uint result) { throw null; } @@ -6419,9 +6500,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static ulong Clamp(ulong value, ulong min, ulong max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(ulong value) { throw null; } - public static ulong CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static ulong CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static ulong CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (ulong Quotient, ulong Remainder) DivRem(ulong left, ulong right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(ulong obj) { throw null; } @@ -6504,6 +6582,12 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static ulong System.Numerics.INumberBase.MaxMagnitudeNumber(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumberBase.MinMagnitude(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumberBase.MinMagnitudeNumber(ulong x, ulong y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static ulong System.Numerics.INumber.CopySign(ulong value, ulong sign) { throw null; } static ulong System.Numerics.INumber.MaxNumber(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumber.MinNumber(ulong x, ulong y) { throw null; } @@ -6520,7 +6604,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; } public static ulong TrailingZeroCount(ulong value) { throw null; } - public static bool TryCreate(TOther value, out ulong result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out ulong result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out ulong result) { throw null; } @@ -6551,9 +6634,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) public static nuint Clamp(nuint value, nuint min, nuint max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(nuint value) { throw null; } - public static nuint CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static nuint CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } - public static nuint CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static (nuint Quotient, nuint Remainder) DivRem(nuint left, nuint right) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(nuint other) { throw null; } @@ -6629,6 +6709,12 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static nuint System.Numerics.INumberBase.MaxMagnitudeNumber(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumberBase.MinMagnitude(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumberBase.MinMagnitudeNumber(nuint x, nuint y) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToChecked(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToSaturating(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase.TryConvertToTruncating(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static nuint System.Numerics.INumber.CopySign(nuint value, nuint sign) { throw null; } static nuint System.Numerics.INumber.MaxNumber(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumber.MinNumber(nuint x, nuint y) { throw null; } @@ -6649,7 +6735,6 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser public uint ToUInt32() { throw null; } public ulong ToUInt64() { throw null; } public static nuint TrailingZeroCount(nuint value) { throw null; } - public static bool TryCreate(TOther value, out nuint result) where TOther : System.Numerics.INumberBase { throw null; } public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out nuint result) { throw null; } public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out nuint result) { throw null; } @@ -10415,9 +10500,9 @@ public partial interface INumberBase : System.IEquatable, System.I static abstract int Radix { get; } static abstract TSelf Zero { get; } static abstract TSelf Abs(TSelf value); - static abstract TSelf CreateChecked(TOther value) where TOther : INumberBase; - static abstract TSelf CreateSaturating(TOther value) where TOther : INumberBase; - static abstract TSelf CreateTruncating(TOther value) where TOther : INumberBase; + static virtual TSelf CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } + static virtual TSelf CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } + static virtual TSelf CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } static abstract bool IsCanonical(TSelf value); static abstract bool IsComplexNumber(TSelf value); static abstract bool IsEvenInteger(TSelf value); @@ -10441,7 +10526,12 @@ public partial interface INumberBase : System.IEquatable, System.I static abstract TSelf MinMagnitudeNumber(TSelf x, TSelf y); static abstract TSelf Parse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider); static abstract TSelf Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider); - static abstract bool TryCreate(TOther value, out TSelf result) where TOther : INumberBase; + protected static abstract bool TryConvertFromChecked(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase; + protected static abstract bool TryConvertFromSaturating(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase; + protected static abstract bool TryConvertFromTruncating(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase; + protected static abstract bool TryConvertToChecked(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase; + protected static abstract bool TryConvertToSaturating(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase; + protected static abstract bool TryConvertToTruncating(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase; static abstract bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out TSelf result); static abstract bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out TSelf result); } diff --git a/src/libraries/System.Runtime/tests/System/ByteTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/ByteTests.GenericMath.cs index 2d5262e7145747..0c30d246fd683a 100644 --- a/src/libraries/System.Runtime/tests/System/ByteTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/ByteTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,66 @@ public static void CreateCheckedFromCharTest() Assert.Throws(() => NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked(+255.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+256.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked((Half)255.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked((Half)256.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +677,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +708,30 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked(+255.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+256.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +742,30 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateChecked(+255.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+256.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +796,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +847,66 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+255.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+256.0)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating((Half)255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating((Half)256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +937,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +968,30 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +1002,30 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1056,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1107,66 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+255.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+256.0)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating((Half)255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating((Half)256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1197,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1228,30 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1262,30 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1316,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1557,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal((byte)0x01, NumberBaseHelper.MinMagnitudeNumber((byte)0xFF, (byte)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((byte)0x01, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((byte)0x7F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((byte)0x80, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((byte)0xFF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - byte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((byte)0x01, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((byte)0x7F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - byte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - byte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/CharTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/CharTests.GenericMath.cs index f471e17249f992..3c33ae7a37ed80 100644 --- a/src/libraries/System.Runtime/tests/System/CharTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/CharTests.GenericMath.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -585,6 +586,64 @@ public static void CreateCheckedFromCharTest() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((char)0x00, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((char)0x00, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((char)0x01, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked(+65535.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -615,6 +674,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -636,6 +705,30 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked(65535.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -646,6 +739,30 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateChecked(+65535.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -676,6 +793,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -717,6 +844,64 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(+65535.0)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -747,6 +932,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -768,6 +963,30 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -778,6 +997,30 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(+65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -808,6 +1051,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -849,6 +1102,64 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(+65535.0)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -879,6 +1190,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -900,6 +1221,30 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -910,6 +1255,30 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(+65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -940,6 +1309,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1171,277 +1550,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal((char)0x0001, NumberBaseHelper.MinMagnitudeNumber((char)0xFFFF, (char)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((char)0x007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((char)0x0080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((char)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((char)0x8000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((char)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - char result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((char)0x007F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((char)0x8000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((char)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - char result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - char result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/DecimalTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/DecimalTests.GenericMath.cs index f49ce0c7c94e42..86dad1e6b1aeca 100644 --- a/src/libraries/System.Runtime/tests/System/DecimalTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/DecimalTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -584,6 +585,65 @@ public static void CreateCheckedFromCharTest() Assert.Equal(65535.0m, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper.CreateChecked(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper.CreateChecked(-79228162514264333195497439231.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+79228162514264337593543950335.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-79228162514264337593543950335.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -646,6 +706,27 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -656,6 +737,33 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper.CreateChecked(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper.CreateChecked(-79228160000000000000000000000.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+79228162514264337593543950335.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-79228162514264337593543950335.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -738,6 +846,65 @@ public static void CreateSaturatingFromCharTest() Assert.Equal(65535.0m, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper.CreateSaturating(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper.CreateSaturating(-79228162514264333195497439231.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(+79228162514264337593543950335.0)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(-79228162514264337593543950335.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -801,6 +968,27 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -811,6 +999,33 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper.CreateSaturating(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper.CreateSaturating(-79228160000000000000000000000.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(+79228162514264337593543950335.0f)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(-79228162514264337593543950335.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -894,6 +1109,65 @@ public static void CreateTruncatingFromCharTest() Assert.Equal(65535.0m, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper.CreateTruncating(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper.CreateTruncating(-79228162514264333195497439231.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(+79228162514264337593543950335.0)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(-79228162514264337593543950335.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -933,7 +1207,7 @@ public static void CreateTruncatingFromInt128Test() Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); - Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); } [Fact] @@ -957,6 +1231,27 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -967,6 +1262,33 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper.CreateTruncating(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper.CreateTruncating(-79228160000000000000000000000.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(+79228162514264337593543950335.0f)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(-79228162514264337593543950335.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1006,7 +1328,7 @@ public static void CreateTruncatingFromUInt128Test() Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); - Assert.Equal(0.0m, NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(decimal.MaxValue, NumberBaseHelper.CreateTruncating(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); } [Fact] @@ -1371,319 +1693,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(1.0m, NumberBaseHelper.MinMagnitudeNumber(decimal.MaxValue, 1.0m)); } - [Fact] - public static void TryCreateFromByteTest() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(128.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(255.0m, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(32768.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(65535.0m, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(-1.0m, result); - - Assert.False(NumberBaseHelper.TryCreate(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper.TryCreate(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - decimal result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(32768.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(65535.0m, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(2147483648.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0m, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0m, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - decimal result; - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0m, result); - - Assert.False(NumberBaseHelper.TryCreate(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper.TryCreate(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper.TryCreate(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - decimal result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(18446744073709551615.0m, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal(2147483648.0m, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(4294967295.0m, result); - } - } - // // ISignedNumber // diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.GenericMath.cs index f0868228a67aa8..a1bae12e9275fd 100644 --- a/src/libraries/System.Runtime/tests/System/DoubleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/DoubleTests.GenericMath.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests { public class DoubleTests_GenericMath { - private const double MinNormal = 2.2250738585072014E-308; + internal const double MinNormal = 2.2250738585072014E-308; - private const double MaxSubnormal = 2.2250738585072009E-308; + internal const double MaxSubnormal = 2.2250738585072009E-308; private static void AssertBitwiseEqual(double expected, double actual) { @@ -1039,6 +1040,69 @@ public static void CreateCheckedFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateChecked(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateChecked(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateChecked(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateChecked(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateChecked(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateChecked(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateChecked(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateChecked(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -1100,6 +1164,49 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1110,6 +1217,32 @@ public static void CreateCheckedFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateChecked(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateChecked(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateChecked(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateChecked(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateChecked(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1195,6 +1328,69 @@ public static void CreateSaturatingFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateSaturating(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateSaturating(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateSaturating(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateSaturating(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateSaturating(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -1256,6 +1452,49 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1266,6 +1505,32 @@ public static void CreateSaturatingFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateSaturating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateSaturating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateSaturating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateSaturating(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1351,6 +1616,69 @@ public static void CreateTruncatingFromCharTest() AssertBitwiseEqual(65535.0, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper.CreateTruncating(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper.CreateTruncating(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper.CreateTruncating(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper.CreateTruncating(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper.CreateTruncating(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -1412,6 +1740,49 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1422,6 +1793,32 @@ public static void CreateTruncatingFromSByteTest() AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper.CreateTruncating(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper.CreateTruncating(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateTruncating(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper.CreateTruncating(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1907,321 +2304,6 @@ public static void MinMagnitudeNumberTest() AssertBitwiseEqual(1.0, NumberBaseHelper.MinMagnitudeNumber(double.PositiveInfinity, 1.0)); } - [Fact] - public static void TryCreateFromByteTest() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(128.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(255.0, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(32768.0, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(65535.0, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(-170141183460469231731687303715884105728.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - double result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(32768.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(65535.0, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(2147483648.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - double result; - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(170141183460469231731687303715884105728.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(340282366920938463463374607431768211456.0, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - double result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal(4294967295.0, result); - } - } - // // ISignedNumber // diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/HalfTests.GenericMath.cs index c3d521808c32e4..4ef1474efc6294 100644 --- a/src/libraries/System.Runtime/tests/System/HalfTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/HalfTests.GenericMath.cs @@ -2,27 +2,28 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests { public class HalfTests_GenericMath { - private static Half MinNormal => BitConverter.UInt16BitsToHalf(0x0400); + internal static Half MinNormal => BitConverter.UInt16BitsToHalf(0x0400); - private static Half MaxSubnormal => BitConverter.UInt16BitsToHalf(0x03FF); + internal static Half MaxSubnormal => BitConverter.UInt16BitsToHalf(0x03FF); - private static Half NegativeOne => BitConverter.UInt16BitsToHalf(0xBC00); + internal static Half NegativeOne => BitConverter.UInt16BitsToHalf(0xBC00); - private static Half NegativeTwo => BitConverter.UInt16BitsToHalf(0xC000); + internal static Half NegativeTwo => BitConverter.UInt16BitsToHalf(0xC000); - private static Half NegativeZero => BitConverter.UInt16BitsToHalf(0x8000); + internal static Half NegativeZero => BitConverter.UInt16BitsToHalf(0x8000); - private static Half One => BitConverter.UInt16BitsToHalf(0x3C00); + internal static Half One => BitConverter.UInt16BitsToHalf(0x3C00); - private static Half Two => BitConverter.UInt16BitsToHalf(0x4000); + internal static Half Two => BitConverter.UInt16BitsToHalf(0x4000); - private static Half Zero => BitConverter.UInt16BitsToHalf(0x0000); + internal static Half Zero => BitConverter.UInt16BitsToHalf(0x0000); private static void AssertBitwiseEqual(Half expected, Half actual) { @@ -1057,6 +1058,70 @@ public static void CreateCheckedFromCharTest() AssertBitwiseEqual((Half)65535.0f, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateChecked(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateChecked(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateChecked(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper.CreateChecked(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateChecked(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateChecked(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper.CreateChecked(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateChecked(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper.CreateChecked(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper.CreateChecked(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateChecked(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper.CreateChecked(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -1118,6 +1183,47 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateChecked(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper.CreateChecked(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1128,6 +1234,32 @@ public static void CreateCheckedFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateChecked(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateChecked(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateChecked(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateChecked(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1213,6 +1345,70 @@ public static void CreateSaturatingFromCharTest() AssertBitwiseEqual((Half)65535.0f, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateSaturating(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateSaturating(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateSaturating(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper.CreateSaturating(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateSaturating(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateSaturating(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper.CreateSaturating(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateSaturating(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper.CreateSaturating(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper.CreateSaturating(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateSaturating(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -1274,6 +1470,47 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateSaturating(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper.CreateSaturating(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1284,6 +1521,32 @@ public static void CreateSaturatingFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateSaturating(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateSaturating(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateSaturating(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1369,6 +1632,70 @@ public static void CreateTruncatingFromCharTest() AssertBitwiseEqual((Half)65535.0f, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateTruncating(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateTruncating(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateTruncating(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper.CreateTruncating(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateTruncating(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateTruncating(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper.CreateTruncating(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper.CreateTruncating(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper.CreateTruncating(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper.CreateTruncating(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateTruncating(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -1430,6 +1757,47 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateTruncating(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper.CreateTruncating(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1440,6 +1808,32 @@ public static void CreateTruncatingFromSByteTest() AssertBitwiseEqual(NegativeOne, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper.CreateTruncating(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper.CreateTruncating(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper.CreateTruncating(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1925,321 +2319,6 @@ public static void MinMagnitudeNumberTest() AssertBitwiseEqual(One, NumberBaseHelper.MinMagnitudeNumber(Half.PositiveInfinity, One)); } - [Fact] - public static void TryCreateFromByteTest() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((Half)127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((Half)128.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((Half)255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((Half)32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((Half)65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((Half)(-32768.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((Half)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal((Half)(-9223372036854775808.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal((Half)170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal((Half)(-170141183460469231731687303715884105728.0), result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - Half result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((Half)(-9223372036854775808.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((Half)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((Half)127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((Half)(-128.0f), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((Half)32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((Half)65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((Half)2147483648.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((Half)4294967295.0f, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((Half)9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)18446744073709551615.0f, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - Half result; - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal((Half)170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal((Half)170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(Half.PositiveInfinity, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - Half result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal((Half)9223372036854775808.0f, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal((Half)18446744073709551615.0f, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - // Assert.Equal((Half)2147483648.0f, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal((Half)4294967295.0f, result); - } - } - // // ISignedNumber // diff --git a/src/libraries/System.Runtime/tests/System/Int128Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/Int128Tests.GenericMath.cs index fd057cbb484699..9b71f495ee6ffe 100644 --- a/src/libraries/System.Runtime/tests/System/Int128Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/Int128Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -673,6 +674,8 @@ public static void CreateCheckedFromDoubleTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); } [Fact] @@ -724,6 +727,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -745,6 +758,48 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateChecked(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper.CreateChecked((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper.CreateChecked(-170141183460469231731687303715884105728.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+170141183460469231731687303715884105728.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-170141203742878835383357727663135391744.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -812,6 +867,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -940,6 +1005,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -961,6 +1036,48 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateSaturating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating(-170141183460469231731687303715884105728.0f)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(+170141183460469231731687303715884105728.0f)); + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating(-170141203742878835383357727663135391744.0f)); + } + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(MinValue, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1027,6 +1144,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1155,6 +1282,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -1176,6 +1313,48 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(-170141183460469231731687303715884105728.0f)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(+170141183460469231731687303715884105728.0f)); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(-170141203742878835383357727663135391744.0f)); + } + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1242,6 +1421,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(NegativeOne, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1473,436 +1662,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(NegativeOne, NumberBaseHelper.MinMagnitudeNumber(NegativeOne, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromDecimalTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(decimal.Zero, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.One, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.MinusOne, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.MaxValue, out result)); - Assert.Equal(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.MinValue, out result)); - Assert.Equal(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001), result); - } - - [Fact] - public static void TryCreateFromDoubleTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(+0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+1.0, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(-1.0, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper.TryCreate(+170141183460469212842221372237303250944.0, out result)); - Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(-170141183460469212842221372237303250944.0, out result)); - Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(-170141183460469231731687303715884105728.0, out result)); - Assert.Equal(MinValue, result); - - Assert.False(NumberBaseHelper.TryCreate(+170141183460469231731687303715884105728.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(-170141183460469269510619166673045815296.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromHalfTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate((Half)(+0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((Half)(-0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((Half)(+1.0), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((Half)(-1.0), out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper.TryCreate(Half.MaxValue, out result)); - Assert.Equal(+65504, result); - - Assert.True(NumberBaseHelper.TryCreate(Half.MinValue, out result)); - Assert.Equal(-65504, result); - - Assert.False(NumberBaseHelper.TryCreate(Half.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(Half.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(Int16MinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - Int128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(SByteMinValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromSingleTest() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(+0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+1.0f, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(-1.0f, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper.TryCreate(+170141173319264429905852091742258462720.0f, out result)); - Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(-170141173319264429905852091742258462720.0f, out result)); - Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(-170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(MinValue, result); - - Assert.False(NumberBaseHelper.TryCreate(+170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(-170141203742878835383357727663135391744.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - Int128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - Int128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(UInt32MaxValue, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/Int16Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/Int16Tests.GenericMath.cs index a2ca19cf854390..e869a8259e940c 100644 --- a/src/libraries/System.Runtime/tests/System/Int16Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/Int16Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,69 @@ public static void CreateCheckedFromCharTest() Assert.Throws(() => NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(-1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateChecked(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked(-32768.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+32768.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-32769.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper.CreateChecked((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked((Half)(-32768.0f))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((Half)32768.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked((Half)(-32800.0f))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +680,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +711,31 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateChecked(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked(-32768.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+32768.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-32769.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +746,31 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateChecked(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateChecked(-32768.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+32768.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-32769.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +801,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +852,69 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(-1.0m)); + + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateSaturating(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32768.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(+32768.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32769.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper.CreateSaturating((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating((Half)(-32768.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating((Half)32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating((Half)(-32800.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +945,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +976,31 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateSaturating(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +1011,31 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateSaturating(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1066,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1117,69 @@ public static void CreateTruncatingFromCharTest() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(-1.0m)); + + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateTruncating(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32768.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(+32768.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32769.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper.CreateTruncating((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating((Half)(-32768.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating((Half)32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating((Half)(-32800.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1210,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((short)0x0000), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1241,31 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateTruncating(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1276,31 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper.CreateTruncating(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1331,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((short)0x0000), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1572,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper.MinMagnitudeNumber(unchecked((short)0xFFFF), (short)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((short)0x007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((short)0x0080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((short)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((short)0x8000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - short result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((short)0x007F, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((short)0xFF80), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - short result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - short result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/Int32Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/Int32Tests.GenericMath.cs index 4246afdda0fb0c..073580354b835d 100644 --- a/src/libraries/System.Runtime/tests/System/Int32Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/Int32Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,63 @@ public static void CreateCheckedFromCharTest() Assert.Equal((int)0x0000FFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateChecked(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483648.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483649.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +674,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +705,42 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateChecked((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateChecked((NFloat)(-2147483648.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(+2147483648.0))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateChecked(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483647.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483904.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +751,31 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateChecked(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483648.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483904.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +806,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +857,63 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((int)0x0000FFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0m)); + + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(+2147483648.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483649.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +944,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +975,42 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-2147483648.0))); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating((NFloat)(+2147483648.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateSaturating(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FF80), NumberBaseHelper.CreateSaturating(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483904.0f)); + } + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +1021,31 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateSaturating(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(+2147483648.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483904.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1076,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((int)0x7FFFFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1127,63 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((int)0x0000FFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0m)); + + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateTruncating(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(+2147483648.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483649.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1214,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1245,42 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper.CreateTruncating((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-2147483648.0))); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating((NFloat)(+2147483648.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateTruncating(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(+2147483647.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483904.0f)); + } + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1291,31 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper.CreateTruncating(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(+2147483648.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483904.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1346,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(unchecked((int)0x0000_0001), NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1587,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper.MinMagnitudeNumber(unchecked((int)0xFFFFFFFF), 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((int)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((int)0x00000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((int)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((int)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((int)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((int)0xFFFF8000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((int)0x80000000)), out result)); - Assert.Equal(unchecked((int)0x80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((int)0xFFFFFFFF)), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - int result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(unchecked((int)0x80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((int)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((int)0xFFFFFF80), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((int)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((int)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(unchecked((int)0x00000000), result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(unchecked((int)0x00000000), result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - int result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - int result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal(unchecked((int)0x00000000), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0x00000000), result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/Int64Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/Int64Tests.GenericMath.cs index bced25ea60754e..831349298dd2f5 100644 --- a/src/libraries/System.Runtime/tests/System/Int64Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/Int64Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,64 @@ public static void CreateCheckedFromCharTest() Assert.Equal((long)0x000000000000FFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateChecked(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+9223372036854775808.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-9223372036854777856.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +675,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateChecked(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +706,43 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateChecked((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(-9223372036854775808.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(+9223372036854775808.0))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateChecked(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+9223372036854775808.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-9223373136366403584.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +753,32 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateChecked(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+9223372036854775808.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-9223373136366403584.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +809,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +860,63 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((long)0x000000000000FFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0m)); + + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateSaturating(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(+9223372036854775808.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854777856.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +947,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateSaturating(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +978,42 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateSaturating((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-9223372036854775808.0))); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating((NFloat)(+9223372036854775808.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateSaturating(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223373136366403584.0f)); + } + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +1024,31 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateSaturating(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223373136366403584.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1079,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((long)0x7FFFFFFFFFFFFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1130,63 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((long)0x000000000000FFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0m)); + + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateTruncating(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(+9223372036854775808.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854777856.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1217,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1248,42 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper.CreateTruncating((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-9223372036854775808.0))); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating((NFloat)(+9223372036854775808.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateTruncating(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223373136366403584.0f)); + } + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1294,31 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper.CreateTruncating(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223373136366403584.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1349,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1590,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper.MinMagnitudeNumber(unchecked((long)0xFFFFFFFFFFFFFFFF), 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((long)0x000000000000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((long)0x0000000000000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((long)0x00000000000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((long)0x0000000000008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((long)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFF8000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFF80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(unchecked((long)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - long result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((long)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFF80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((long)0x000000000000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFF80), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((long)0x0000000000008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((long)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((long)0x0000000080000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((long)0x00000000FFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - long result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - long result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((long)0x0000000080000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((long)0x00000000FFFFFFFF, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/IntPtrTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/IntPtrTests.GenericMath.cs index 6817debb45ef9b..4af074c3d5c196 100644 --- a/src/libraries/System.Runtime/tests/System/IntPtrTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/IntPtrTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -1094,7 +1095,97 @@ public static void CreateCheckedFromCharTest() } [Fact] - public static void CreateCheckedFroMinMagnitudet16Test() + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0m)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateChecked(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+9223372036854775808.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateChecked(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483648.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483649.0)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateChecked(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper.CreateChecked(Half.MinValue)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateChecked(0x0000)); Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateChecked(0x0001)); @@ -1104,7 +1195,7 @@ public static void CreateCheckedFroMinMagnitudet16Test() } [Fact] - public static void CreateCheckedFroMinMagnitudet32Test() + public static void CreateCheckedFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateChecked(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateChecked(0x00000001)); @@ -1114,7 +1205,7 @@ public static void CreateCheckedFroMinMagnitudet32Test() } [Fact] - public static void CreateCheckedFroMinMagnitudet64Test() + public static void CreateCheckedFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1135,7 +1226,25 @@ public static void CreateCheckedFroMinMagnitudet64Test() } [Fact] - public static void CreateCheckedFroMinMagnitudetPtrTest() + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1155,6 +1264,46 @@ public static void CreateCheckedFroMinMagnitudetPtrTest() } } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateChecked((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(-9223372036854775808.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(+9223372036854775808.0))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateChecked(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483648.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483904.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1165,6 +1314,46 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper.CreateChecked(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateChecked(-9223372036854775808.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+9223372036854775808.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateChecked(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateChecked(-2147483648.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+2147483648.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-2147483904.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1217,6 +1406,16 @@ public static void CreateCheckedFromUInt64Test() } } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -1259,7 +1458,96 @@ public static void CreateSaturatingFromCharTest() } [Fact] - public static void CreateSaturatingFroMinMagnitudet16Test() + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0m)); + } + + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateSaturating(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(+9223372036854775808.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateSaturating(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(+2147483648.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(-2147483649.0)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateSaturating(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper.CreateSaturating(Half.MinValue)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateSaturating(0x0000)); Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateSaturating(0x0001)); @@ -1269,7 +1557,7 @@ public static void CreateSaturatingFroMinMagnitudet16Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudet32Test() + public static void CreateSaturatingFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateSaturating(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateSaturating(0x00000001)); @@ -1279,7 +1567,7 @@ public static void CreateSaturatingFroMinMagnitudet32Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudet64Test() + public static void CreateSaturatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1300,7 +1588,26 @@ public static void CreateSaturatingFroMinMagnitudet64Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudetPtrTest() + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1320,6 +1627,45 @@ public static void CreateSaturatingFroMinMagnitudetPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateSaturating((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(-9223372036854775808.0))); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating((NFloat)(+9223372036854775808.0))); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateSaturating(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1330,6 +1676,45 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper.CreateSaturating(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateSaturating(-9223372036854775808.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(+9223372036854775808.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateSaturating(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateSaturating(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1382,6 +1767,16 @@ public static void CreateSaturatingFromUInt64Test() } } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1424,7 +1819,96 @@ public static void CreateTruncatingFromCharTest() } [Fact] - public static void CreateTruncatingFroMinMagnitudet16Test() + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0m)); + } + + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateTruncating(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(+9223372036854775808.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper.CreateTruncating(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(+2147483648.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(-2147483649.0)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper.CreateTruncating(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper.CreateTruncating(Half.MinValue)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromInt16Test() { if (Environment.Is64BitProcess) { @@ -1445,7 +1929,7 @@ public static void CreateTruncatingFroMinMagnitudet16Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudet32Test() + public static void CreateTruncatingFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper.CreateTruncating(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper.CreateTruncating(0x00000001)); @@ -1455,7 +1939,7 @@ public static void CreateTruncatingFroMinMagnitudet32Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudet64Test() + public static void CreateTruncatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1476,7 +1960,27 @@ public static void CreateTruncatingFroMinMagnitudet64Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudetPtrTest() + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(Int128.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1496,6 +2000,45 @@ public static void CreateTruncatingFroMinMagnitudetPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper.CreateTruncating((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(-9223372036854775808.0))); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating((NFloat)(+9223372036854775808.0))); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateTruncating(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1517,6 +2060,45 @@ public static void CreateTruncatingFromSByteTest() } } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper.CreateTruncating(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper.CreateTruncating(-9223372036854775808.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(+9223372036854775808.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper.CreateTruncating(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper.CreateTruncating(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1558,6 +2140,26 @@ public static void CreateTruncatingFromUInt64Test() } } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -2020,337 +2622,6 @@ public static void MinMagnitudeNumberTest() } } - [Fact] - public static void TryCreateFromByteTest() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((nint)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((nint)0x00000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((nint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((nint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((nint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet16Test() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFF8000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet32Test() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(unchecked((nint)(int)0x80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet64Test() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(unchecked((nint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFroMinMagnitudetPtrTest() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((nint)0x80000000)), out result)); - Assert.Equal(unchecked((nint)0x80000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((nint)0xFFFFFFFF)), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((nint)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFF80), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - nint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((nint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((nint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(unchecked((nint)0x0000000080000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x00000000FFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(unchecked((nint)0x00000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((nint)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((nint)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((nint)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked(unchecked((nuint)0x80000000)), out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked(unchecked((nuint)0xFFFFFFFF)), out result)); - Assert.Equal((nint)0x00000000, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/SByteTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/SByteTests.GenericMath.cs index b0be250fc68892..3415a85dd7906f 100644 --- a/src/libraries/System.Runtime/tests/System/SByteTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/SByteTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,69 @@ public static void CreateCheckedFromCharTest() Assert.Throws(() => NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(-1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateChecked(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked(-128.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+128.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-129.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateChecked((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked((Half)(-128.0f))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((Half)(+128.0f))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((Half)(-129.0f))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +680,16 @@ public static void CreateCheckedFromInt64Test() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +711,31 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateChecked(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked(-128.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+128.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-129.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +746,31 @@ public static void CreateCheckedFromSByteTest() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateChecked(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateChecked(-128.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(+128.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-129.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +801,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +852,69 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(-1.0m)); + + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-128.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(+128.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-129.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating((Half)(-128.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating((Half)(+128.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating((Half)(-129.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(Half.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(Half.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +945,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +976,31 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +1011,31 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1066,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1117,69 @@ public static void CreateTruncatingFromCharTest() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(-1.0m)); + + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateTruncating(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-128.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(+128.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-129.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateTruncating((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating((Half)(-128.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating((Half)(+128.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating((Half)(-129.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(Half.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(Half.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1210,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(unchecked((sbyte)0x01), NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1241,31 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateTruncating(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1276,31 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper.CreateTruncating(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1331,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(unchecked((sbyte)0x01), NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1572,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper.MinMagnitudeNumber(unchecked((sbyte)0xFF), (sbyte)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((sbyte)0x7F, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - sbyte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((sbyte)0x7F, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((sbyte)0x80), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - sbyte result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - sbyte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/SingleTests.GenericMath.cs index 4692ecfe55ee40..709bd3d04926e3 100644 --- a/src/libraries/System.Runtime/tests/System/SingleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/SingleTests.GenericMath.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests { public class SingleTests_GenericMath { - private const float MinNormal = 1.17549435E-38f; + internal const float MinNormal = 1.17549435E-38f; - private const float MaxSubnormal = 1.17549421E-38f; + internal const float MaxSubnormal = 1.17549421E-38f; private static void AssertBitwiseEqual(float expected, float actual) { @@ -1039,6 +1040,69 @@ public static void CreateCheckedFromCharTest() AssertBitwiseEqual(65535.0f, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateChecked(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateChecked(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateChecked(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateChecked(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateChecked(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateChecked(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateChecked(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -1100,6 +1164,51 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateChecked(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1110,6 +1219,32 @@ public static void CreateCheckedFromSByteTest() AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateChecked(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateChecked(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateChecked(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateChecked(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateChecked(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateChecked(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateChecked(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateChecked(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateChecked(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateChecked(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateChecked(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateChecked(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1195,6 +1330,69 @@ public static void CreateSaturatingFromCharTest() AssertBitwiseEqual(65535.0f, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateSaturating(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateSaturating(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateSaturating(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateSaturating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateSaturating(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateSaturating(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -1256,6 +1454,51 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateSaturating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1266,6 +1509,32 @@ public static void CreateSaturatingFromSByteTest() AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateSaturating(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateSaturating(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateSaturating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateSaturating(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateSaturating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateSaturating(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateSaturating(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateSaturating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateSaturating(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateSaturating(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateSaturating(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1351,6 +1620,69 @@ public static void CreateTruncatingFromCharTest() AssertBitwiseEqual(65535.0f, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper.CreateTruncating(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper.CreateTruncating(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper.CreateTruncating(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper.CreateTruncating(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper.CreateTruncating(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper.CreateTruncating(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -1412,6 +1744,51 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateTruncating(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1422,6 +1799,32 @@ public static void CreateTruncatingFromSByteTest() AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper.CreateTruncating(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper.CreateTruncating(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper.CreateTruncating(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper.CreateTruncating(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper.CreateTruncating(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper.CreateTruncating(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper.CreateTruncating(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper.CreateTruncating(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper.CreateTruncating(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper.CreateTruncating(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper.CreateTruncating(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1907,321 +2310,6 @@ public static void MinMagnitudeNumberTest() AssertBitwiseEqual(1.0f, NumberBaseHelper.MinMagnitudeNumber(float.PositiveInfinity, 1.0f)); } - [Fact] - public static void TryCreateFromByteTest() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(128.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(-170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - float result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(127.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(32768.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(2147483648.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0f, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0f, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - float result; - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(float.PositiveInfinity, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - float result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0f, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0f, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0f, result); - // - // Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal(4294967295.0f, result); - } - } - // // ISignedNumber // diff --git a/src/libraries/System.Runtime/tests/System/UInt128Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UInt128Tests.GenericMath.cs index c572abcf2a673f..a6912f17c00282 100644 --- a/src/libraries/System.Runtime/tests/System/UInt128Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UInt128Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -720,6 +721,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -741,6 +752,40 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Throws(() => NumberBaseHelper.CreateChecked((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateChecked(float.MaxValue)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -801,6 +846,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateChecked(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateChecked(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -927,6 +982,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -948,6 +1013,40 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateSaturating(float.MaxValue)); + } + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(-1.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1008,6 +1107,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateSaturating(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateSaturating(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1134,6 +1243,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -1155,6 +1274,40 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper.CreateTruncating(float.MaxValue)); + } + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(-1.0f)); + + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1215,6 +1368,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal(UInt64MaxValue, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper.CreateTruncating(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper.CreateTruncating(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1446,421 +1609,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal(One, NumberBaseHelper.MinMagnitudeNumber(MaxValue, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromDecimalTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(decimal.Zero, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.One, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(decimal.MaxValue, out result)); - Assert.Equal(new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), result); - - Assert.False(NumberBaseHelper.TryCreate(decimal.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(decimal.MinusOne, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromDoubleTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(+0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+1.0, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(+170141183460469231731687303715884105728.0, out result)); - Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(+340282366920938425684442744474606501888.0, out result)); - Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), result); - - Assert.False(NumberBaseHelper.TryCreate(-double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(-1.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(+340282366920938463463374607431768211456.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(-340282366920938425684442744474606501888.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(double.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromHalfTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate((Half)(+0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((Half)(-0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((Half)(+1.0), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(Half.MaxValue, out result)); - Assert.Equal(+65504U, result); - - Assert.False(NumberBaseHelper.TryCreate(-Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate((Half)(-1.0), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(Half.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(Half.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(Half.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - UInt128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromSingleTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(+0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(-0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(+1.0f, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(+170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper.TryCreate(float.MaxValue, out result)); - Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.False(NumberBaseHelper.TryCreate(-float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(-1.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper.TryCreate(float.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - UInt128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(UInt32MaxValue, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/UInt16Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UInt16Tests.GenericMath.cs index 1cb5e4388ea3b8..9cf4fa0c6facf5 100644 --- a/src/libraries/System.Runtime/tests/System/UInt16Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UInt16Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -586,6 +587,64 @@ public static void CreateCheckedFromCharTest() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked(+65535.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -616,6 +675,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -637,6 +706,30 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked(65535.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -647,6 +740,30 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateChecked(+65535.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+65536.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -677,6 +794,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -718,6 +845,64 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(+65535.0)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -748,6 +933,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -769,6 +964,30 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -779,6 +998,30 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(+65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -809,6 +1052,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -850,6 +1103,64 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(+65535.0)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -880,6 +1191,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -901,6 +1222,30 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -911,6 +1256,30 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(+65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -941,6 +1310,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1172,277 +1551,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal((ushort)0x0001, NumberBaseHelper.MinMagnitudeNumber((ushort)0xFFFF, (ushort)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((ushort)0x007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((ushort)0x0080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((ushort)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((ushort)0x8000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((ushort)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - ushort result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((ushort)0x007F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((ushort)0x8000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((ushort)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - ushort result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - ushort result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/UInt32Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UInt32Tests.GenericMath.cs index 06ee6bd14d3319..a2a44eac10a519 100644 --- a/src/libraries/System.Runtime/tests/System/UInt32Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UInt32Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -587,6 +588,64 @@ public static void CreateCheckedFromCharTest() Assert.Equal((uint)0x0000FFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked(+4294967295.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -617,6 +676,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((uint)0x00000001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -638,6 +707,41 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked((NFloat)(4294967295.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateChecked(4294967040.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -648,6 +752,30 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateChecked(+4294967040.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -678,6 +806,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((uint)0x00000001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -719,6 +857,64 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((uint)0x0000FFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967295.0)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967296.0)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -749,6 +945,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -770,6 +976,41 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating((NFloat)(4294967295.0))); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateSaturating(4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967296.0f)); + } + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -780,6 +1021,30 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((uint)0x00000000, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateSaturating(+4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967296.0f)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -810,6 +1075,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -851,6 +1126,64 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((uint)0x0000FFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967295.0)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967296.0)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -881,6 +1214,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -902,6 +1245,41 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating((NFloat)(4294967295.0))); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateTruncating(4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967296.0f)); + } + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -912,6 +1290,30 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper.CreateTruncating(+4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967296.0f)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -942,6 +1344,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1173,277 +1585,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal((uint)0x00000001, NumberBaseHelper.MinMagnitudeNumber((uint)0xFFFFFFFF, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((uint)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((uint)0x00000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((uint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((uint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((uint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - uint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((uint)0x0000007F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((uint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((uint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((uint)0x80000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((uint)0xFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - uint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - uint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((uint)0x80000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((uint)0xFFFFFFFF, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs index 71a99821a98c94..6a30d6e12feae3 100644 --- a/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -585,6 +586,64 @@ public static void CreateCheckedFromCharTest() Assert.Equal((ulong)0x000000000000FFFF, NumberBaseHelper.CreateChecked((char)0xFFFF)); } + [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateChecked(+18446744073709549568.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + [Fact] public static void CreateCheckedFromInt16Test() { @@ -615,6 +674,16 @@ public static void CreateCheckedFromInt64Test() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + [Fact] public static void CreateCheckedFromIntPtrTest() { @@ -636,6 +705,42 @@ public static void CreateCheckedFromIntPtrTest() } } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateChecked((NFloat)(18446744073709549568.0))); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateChecked(18446742974197923840.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -646,6 +751,31 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateChecked(+18446742974197923840.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -676,6 +806,16 @@ public static void CreateCheckedFromUInt64Test() Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateChecked(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -717,6 +857,64 @@ public static void CreateSaturatingFromCharTest() Assert.Equal((ulong)0x000000000000FFFF, NumberBaseHelper.CreateSaturating((char)0xFFFF)); } + [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateSaturating(+18446744073709549568.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(+18446744073709551616.0)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + [Fact] public static void CreateSaturatingFromInt16Test() { @@ -747,6 +945,16 @@ public static void CreateSaturatingFromInt64Test() Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateSaturating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + [Fact] public static void CreateSaturatingFromIntPtrTest() { @@ -768,6 +976,41 @@ public static void CreateSaturatingFromIntPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateSaturating((NFloat)(18446744073709549568.0))); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateSaturating(18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(+18446744073709551616.0f)); + } + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -778,6 +1021,30 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateSaturating(+18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(+18446744073709551616.0f)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -808,6 +1075,16 @@ public static void CreateSaturatingFromUInt64Test() Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateSaturating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -849,6 +1126,64 @@ public static void CreateTruncatingFromCharTest() Assert.Equal((ulong)0x000000000000FFFF, NumberBaseHelper.CreateTruncating((char)0xFFFF)); } + [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateTruncating(+18446744073709549568.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(+18446744073709551616.0)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + [Fact] public static void CreateTruncatingFromInt16Test() { @@ -879,6 +1214,16 @@ public static void CreateTruncatingFromInt64Test() Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateTruncating(unchecked((long)0xFFFFFFFFFFFFFFFF))); } + [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + [Fact] public static void CreateTruncatingFromIntPtrTest() { @@ -900,6 +1245,41 @@ public static void CreateTruncatingFromIntPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper.CreateTruncating((NFloat)(18446744073709549568.0))); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateTruncating(18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(+18446744073709551616.0f)); + } + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -910,6 +1290,30 @@ public static void CreateTruncatingFromSByteTest() Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateTruncating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper.CreateTruncating(+18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(+18446744073709551616.0f)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -940,6 +1344,16 @@ public static void CreateTruncatingFromUInt64Test() Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper.CreateTruncating(0xFFFFFFFFFFFFFFFF)); } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -1171,277 +1585,6 @@ public static void MinMagnitudeNumberTest() Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper.MinMagnitudeNumber((ulong)0xFFFFFFFFFFFFFFFF, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((ulong)0x000000000000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((ulong)0x0000000000000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((ulong)0x00000000000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((ulong)0x0000000000008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((ulong)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - ulong result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((ulong)0x000000000000007F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((ulong)0x0000000000008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((ulong)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((ulong)0x0000000080000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((ulong)0x00000000FFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - ulong result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((ulong)0x8000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - ulong result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((ulong)0x8000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((ulong)0x0000000080000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((ulong)0x00000000FFFFFFFF, result); - } - } - // // IShiftOperators // diff --git a/src/libraries/System.Runtime/tests/System/UIntPtrTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UIntPtrTests.GenericMath.cs index 7cba3bc55eb6b9..2318aefbd22e1e 100644 --- a/src/libraries/System.Runtime/tests/System/UIntPtrTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UIntPtrTests.GenericMath.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.InteropServices; using Xunit; namespace System.Tests @@ -1086,7 +1087,77 @@ public static void CreateCheckedFromCharTest() } [Fact] - public static void CreateCheckedFroMinMagnitudet16Test() + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateChecked(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper.CreateChecked(+1.0m)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(decimal.MinusOne)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0)); + + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateChecked(+18446744073709549568.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateChecked(+4294967295.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper.CreateChecked(Half.MaxValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeOne)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Half.NaN)); + } + + [Fact] + public static void CreateCheckedFromInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateChecked(0x0000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateChecked(0x0001)); @@ -1096,7 +1167,7 @@ public static void CreateCheckedFroMinMagnitudet16Test() } [Fact] - public static void CreateCheckedFroMinMagnitudet32Test() + public static void CreateCheckedFromInt32Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateChecked(0x00000000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateChecked(0x00000001)); @@ -1106,7 +1177,7 @@ public static void CreateCheckedFroMinMagnitudet32Test() } [Fact] - public static void CreateCheckedFroMinMagnitudet64Test() + public static void CreateCheckedFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1127,7 +1198,17 @@ public static void CreateCheckedFroMinMagnitudet64Test() } [Fact] - public static void CreateCheckedFroMinMagnitudetPtrTest() + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateChecked(Int128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateChecked(Int128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.MinValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(Int128.NegativeOne)); + } + + [Fact] + public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1147,6 +1228,42 @@ public static void CreateCheckedFroMinMagnitudetPtrTest() } } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateChecked((NFloat)18446744073709549568.0)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateChecked(4294967040.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(NFloat.NaN)); + } + [Fact] public static void CreateCheckedFromSByteTest() { @@ -1157,6 +1274,42 @@ public static void CreateCheckedFromSByteTest() Assert.Throws(() => NumberBaseHelper.CreateChecked(unchecked((sbyte)0xFF))); } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateChecked(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper.CreateChecked(+18446742974197923840.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateChecked(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateChecked(+4294967040.0f)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(-1.0f)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(+4294967296.0f)); + } + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.PositiveInfinity)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NegativeInfinity)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.MinValue)); + + Assert.Throws(() => NumberBaseHelper.CreateChecked(float.NaN)); + } + [Fact] public static void CreateCheckedFromUInt16Test() { @@ -1198,6 +1351,16 @@ public static void CreateCheckedFromUInt64Test() } } + [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateChecked(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateChecked(UInt128.One)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws(() => NumberBaseHelper.CreateChecked(UInt128.MaxValue)); + } + [Fact] public static void CreateCheckedFromUIntPtrTest() { @@ -1240,7 +1403,75 @@ public static void CreateSaturatingFromCharTest() } [Fact] - public static void CreateSaturatingFroMinMagnitudet16Test() + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper.CreateSaturating(+1.0m)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(decimal.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(decimal.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateSaturating(+18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateSaturating(+4294967295.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+4294967296.0)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(double.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(double.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(double.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(double.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper.CreateSaturating(Half.MaxValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Half.NegativeOne)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(Half.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Half.NegativeInfinity)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Half.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Half.NaN)); + } + + [Fact] + public static void CreateSaturatingFromInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateSaturating(0x0000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateSaturating(0x0001)); @@ -1250,7 +1481,7 @@ public static void CreateSaturatingFroMinMagnitudet16Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudet32Test() + public static void CreateSaturatingFromInt32Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateSaturating(0x00000000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateSaturating(0x00000001)); @@ -1260,7 +1491,7 @@ public static void CreateSaturatingFroMinMagnitudet32Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudet64Test() + public static void CreateSaturatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1281,7 +1512,17 @@ public static void CreateSaturatingFroMinMagnitudet64Test() } [Fact] - public static void CreateSaturatingFroMinMagnitudetPtrTest() + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(Int128.Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(Int128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Int128.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + } + + [Fact] + public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1301,6 +1542,41 @@ public static void CreateSaturatingFroMinMagnitudetPtrTest() } } + [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateSaturating((NFloat)18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateSaturating(4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(NFloat.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(NFloat.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(NFloat.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(NFloat.NaN)); + } + [Fact] public static void CreateSaturatingFromSByteTest() { @@ -1311,6 +1587,41 @@ public static void CreateSaturatingFromSByteTest() Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateSaturating(unchecked((sbyte)0xFF))); } + [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateSaturating(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper.CreateSaturating(+18446742974197923840.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateSaturating(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateSaturating(+4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(float.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(float.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(float.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(float.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateSaturating(float.NaN)); + } + [Fact] public static void CreateSaturatingFromUInt16Test() { @@ -1352,6 +1663,16 @@ public static void CreateSaturatingFromUInt64Test() } } + [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateSaturating(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateSaturating(UInt128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateSaturating(UInt128.MaxValue)); + } + [Fact] public static void CreateSaturatingFromUIntPtrTest() { @@ -1394,7 +1715,75 @@ public static void CreateTruncatingFromCharTest() } [Fact] - public static void CreateTruncatingFroMinMagnitudet16Test() + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper.CreateTruncating(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper.CreateTruncating(+1.0m)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(decimal.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(decimal.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateTruncating(+18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper.CreateTruncating(+4294967295.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+4294967296.0)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(double.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(double.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(double.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(double.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateTruncating(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper.CreateTruncating(Half.MaxValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(Half.NegativeOne)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(Half.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(Half.NegativeInfinity)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(Half.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(Half.NaN)); + } + + [Fact] + public static void CreateTruncatingFromInt16Test() { if (Environment.Is64BitProcess) { @@ -1415,7 +1804,7 @@ public static void CreateTruncatingFroMinMagnitudet16Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudet32Test() + public static void CreateTruncatingFromInt32Test() { if (Environment.Is64BitProcess) { @@ -1436,7 +1825,7 @@ public static void CreateTruncatingFroMinMagnitudet32Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudet64Test() + public static void CreateTruncatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1457,7 +1846,17 @@ public static void CreateTruncatingFroMinMagnitudet64Test() } [Fact] - public static void CreateTruncatingFroMinMagnitudetPtrTest() + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(Int128.Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateTruncating(Int128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(Int128.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(Int128.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(Int128.NegativeOne)); + } + + [Fact] + public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1477,6 +1876,41 @@ public static void CreateTruncatingFroMinMagnitudetPtrTest() } } + [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper.CreateTruncating((NFloat)18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateTruncating(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateTruncating(4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(NFloat.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(NFloat.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(NFloat.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(NFloat.NaN)); + } + [Fact] public static void CreateTruncatingFromSByteTest() { @@ -1498,6 +1932,41 @@ public static void CreateTruncatingFromSByteTest() } } + [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper.CreateTruncating(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper.CreateTruncating(+18446742974197923840.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper.CreateTruncating(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper.CreateTruncating(+4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(float.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(float.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(float.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(float.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(float.NaN)); + } + [Fact] public static void CreateTruncatingFromUInt16Test() { @@ -1539,6 +2008,16 @@ public static void CreateTruncatingFromUInt64Test() } } + [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper.CreateTruncating(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper.CreateTruncating(UInt128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper.CreateTruncating(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper.CreateTruncating(UInt128.MaxValue)); + } + [Fact] public static void CreateTruncatingFromUIntPtrTest() { @@ -2001,317 +2480,6 @@ public static void MinMagnitudeNumberTest() } } - [Fact] - public static void TryCreateFromByteTest() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((nuint)0x0000007F, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80, out result)); - Assert.Equal((nuint)0x00000080, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFF, out result)); - Assert.Equal((nuint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate((char)0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0x8000, out result)); - Assert.Equal((nuint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate((char)0xFFFF, out result)); - Assert.Equal((nuint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet16Test() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0x8000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((short)0xFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet32Test() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0x80000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet64Test() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFroMinMagnitudetPtrTest() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nint)0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0x80000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x01, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7F, out result)); - Assert.Equal((nuint)0x0000007F, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0x80), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(unchecked((sbyte)0xFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000, out result)); - Assert.Equal((nuint)0x00008000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFF, out result)); - Assert.Equal((nuint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - nuint result; - - Assert.True(NumberBaseHelper.TryCreate(0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(0x80000000, out result)); - Assert.Equal((nuint)0x80000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFF, out result)); - Assert.Equal((nuint)0xFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal(unchecked((nuint)0x00000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate(0x0000000000000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.False(NumberBaseHelper.TryCreate(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0x8000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper.TryCreate(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper.TryCreate((nuint)0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0x80000000), out result)); - Assert.Equal((nuint)0x80000000, result); - - Assert.True(NumberBaseHelper.TryCreate(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0xFFFFFFFF, result); - } - } - // // IShiftOperators //