diff options
author | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2022-06-02 06:37:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-02 06:37:37 +0300 |
commit | 425fedc0fb005af24765faa3ed423222a7dbd963 (patch) | |
tree | d48cf12add42c76ef62844b41467f64087efce5a | |
parent | e8dfdb057f6e0c1afcb526da677b9fadb6ddefd1 (diff) |
[release/7.0-preview5] Refactoring the generic-math CreateChecked/Saturating/Truncating APIs to match API review (#70034)v7.0.0-preview.5.22301.12
* Update MicrosoftNetCompilersToolsetVersion to 4.3.0-2.22270.4
* Moving System.Runtime.InteropServices.NFloat down to System.Runtime
* Removing the generic-math CreateChecked, CreateSaturating, CreateTruncating, and TryCreate implementations
* Removing the generic-math TryCreate tests
* Adding the TryConvertTo* and TryConvertFrom* generic math APIs for Checked, Saturating, and Truncating
* Filling out test coverage for the CreateChecked generic-math API
* Fix some edge cases for the CreateSaturating generic-math APIs
* Filling out test coverage for the CreateSaturating generic-math API
* Fix some edge cases for the CreateTruncating generic-math APIs
* Filling out test coverage for the CreateTruncating generic-math API
* Fixing some edge cases in converting BigInteger/Complex to the primitive types
* Filling out test coverage for converting BigInteger and Complex to the primitive types
* Fixing some 32-bit generic-math tests
* Removing the static virtual declarations since things are falling over
* Skipping some tests on Mono where it has bad behavior
* Revert "Removing the static virtual declarations since things are falling over"
This reverts commit baf69de8576f8528125e6ddee518d3dd310e9e9b.
* Move NFloat back to System.Runtime.InteropServices based on feedback
* Fixing the Int128/UInt128 to Decimal tests
* Ensure `JIT_Dbl2ULng` correctly handles NaN
* Revert "Ensure `JIT_Dbl2ULng` correctly handles NaN"
This reverts commit 329834538e262318f5cf599d9e98a748b9f6a8b9.
* Explicitly ensure floating-point to ulong conversion returns 0 for NaN
* Add default method support to virtual statics (#69783)
Corresponds to #64717 that I somehow missed, despite commenting on it.
We still don't allow interfaces to implement methods of other interfaces. The CLR VM doesn't allow either.
Co-authored-by: Tanner Gooding <tagoo@outlook.com>
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
53 files changed, 17286 insertions, 11273 deletions
diff --git a/eng/Versions.props b/eng/Versions.props index 53f4052e9f3..9453847bc30 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -49,7 +49,7 @@ <!-- TODO: Remove pinned version once arcade supplies a 4.3 compiler. --> - <MicrosoftNetCompilersToolsetVersion>4.3.0-2.22270.2</MicrosoftNetCompilersToolsetVersion> + <MicrosoftNetCompilersToolsetVersion>4.3.0-2.22270.4</MicrosoftNetCompilersToolsetVersion> <!-- SDK dependencies --> <MicrosoftDotNetCompatibilityVersion>2.0.0-preview.4.22252.4</MicrosoftDotNetCompatibilityVersion> <!-- Arcade dependencies --> diff --git a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs index ae94eb660fd..287c410e16d 100644 --- a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs +++ b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs @@ -562,6 +562,16 @@ namespace ILCompiler 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 3da65b1530e..88f726c26d0 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 @@ namespace ILCompiler.DependencyAnalysis if (instantiatedConstrainedMethod.Signature.IsStatic) { implMethod = instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(instantiatedConstrainedMethod); + if (implMethod == null && !instantiatedConstrainedMethod.IsAbstract) + { + implMethod = instantiatedConstrainedMethod; + } } else { @@ -1451,7 +1455,6 @@ namespace ILCompiler.DependencyAnalysis // 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 c07d679f9be..c0850138a72 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 @@ namespace Internal.IL 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 1896db9fae8..141b98bf5d9 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 @@ namespace Internal.JitInterface 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 1814ff4de26..5aae97dd5cb 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 b2ce6e4896f..c6bbb21304f 100644 --- a/src/libraries/Common/tests/System/GenericMathHelpers.cs +++ b/src/libraries/Common/tests/System/GenericMathHelpers.cs @@ -358,9 +358,6 @@ namespace System public static TSelf Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider) => TSelf.Parse(s, style, provider); - public static bool TryCreate<TOther>(TOther value, out TSelf result) - where TOther : INumberBase<TOther> => 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<char> 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 0104da49a46..f8bf9347ec5 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static byte INumberBase<byte>.Abs(byte value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<byte>.IsCanonical(byte value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<byte>.IsComplexNumber(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(byte value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<byte>.IsFinite(byte value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<byte>.IsImaginaryNumber(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<byte>.IsInfinity(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<byte>.IsInteger(byte value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<byte>.IsNaN(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<byte>.IsNegative(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<byte>.IsNegativeInfinity(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<byte>.IsNormal(byte value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(byte value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<byte>.IsPositive(byte value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<byte>.IsPositiveInfinity(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<byte>.IsRealNumber(byte value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<byte>.IsSubnormal(byte value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<byte>.IsZero(byte value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static byte INumberBase<byte>.MaxMagnitude(byte x, byte y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static byte INumberBase<byte>.MaxMagnitudeNumber(byte x, byte y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static byte INumberBase<byte>.MinMagnitude(byte x, byte y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static byte INumberBase<byte>.MinMagnitudeNumber(byte x, byte y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<byte>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<byte>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<byte>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<byte>.TryConvertToChecked<TOther>(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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<byte>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<byte>.IsCanonical(byte value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<byte>.IsComplexNumber(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(byte value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<byte>.IsFinite(byte value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<byte>.IsImaginaryNumber(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<byte>.IsInfinity(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<byte>.IsInteger(byte value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<byte>.IsNaN(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<byte>.IsNegative(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<byte>.IsNegativeInfinity(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<byte>.IsNormal(byte value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(byte value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<byte>.IsPositive(byte value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<byte>.IsPositiveInfinity(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<byte>.IsRealNumber(byte value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<byte>.IsSubnormal(byte value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<byte>.IsZero(byte value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static byte INumberBase<byte>.MaxMagnitude(byte x, byte y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static byte INumberBase<byte>.MaxMagnitudeNumber(byte x, byte y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static byte INumberBase<byte>.MinMagnitude(byte x, byte y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static byte INumberBase<byte>.MinMagnitudeNumber(byte x, byte y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out byte result) - where TOther : INumberBase<TOther> - { - 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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<byte>.TryConvertToTruncating<TOther>(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 fd3b1280859..fa100bbb36e 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static char INumberBase<char>.Abs(char value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase<char>.CreateChecked<TOther>(TOther value) + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<char>.IsCanonical(char value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<char>.IsComplexNumber(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + static bool INumberBase<char>.IsEvenInteger(char value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<char>.IsFinite(char value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<char>.IsImaginaryNumber(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<char>.IsInfinity(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<char>.IsInteger(char value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<char>.IsNaN(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<char>.IsNegative(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<char>.IsNegativeInfinity(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<char>.IsNormal(char value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + static bool INumberBase<char>.IsOddInteger(char value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<char>.IsPositive(char value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<char>.IsPositiveInfinity(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<char>.IsRealNumber(char value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<char>.IsSubnormal(char value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<char>.IsZero(char value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static char INumberBase<char>.MaxMagnitude(char x, char y) => (char)Math.Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static char INumberBase<char>.MaxMagnitudeNumber(char x, char y) => (char)Math.Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static char INumberBase<char>.MinMagnitude(char x, char y) => (char)Math.Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static char INumberBase<char>.MinMagnitudeNumber(char x, char y) => (char)Math.Min(x, y); + + static char INumberBase<char>.Parse(string s, NumberStyles style, IFormatProvider? provider) => Parse(s); + + static char INumberBase<char>.Parse(ReadOnlySpan<char> 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]; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<char>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase<char>.CreateSaturating<TOther>(TOther value) + static bool INumberBase<char>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<char>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - static char INumberBase<char>.CreateTruncating<TOther>(TOther value) + static bool INumberBase<char>.TryConvertToChecked<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<char>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<char>.IsCanonical(char value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<char>.IsComplexNumber(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - static bool INumberBase<char>.IsEvenInteger(char value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<char>.IsFinite(char value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<char>.IsImaginaryNumber(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<char>.IsInfinity(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<char>.IsInteger(char value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<char>.IsNaN(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<char>.IsNegative(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<char>.IsNegativeInfinity(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<char>.IsNormal(char value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - static bool INumberBase<char>.IsOddInteger(char value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<char>.IsPositive(char value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<char>.IsPositiveInfinity(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<char>.IsRealNumber(char value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<char>.IsSubnormal(char value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<char>.IsZero(char value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static char INumberBase<char>.MaxMagnitude(char x, char y) => (char)Math.Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static char INumberBase<char>.MaxMagnitudeNumber(char x, char y) => (char)Math.Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static char INumberBase<char>.MinMagnitude(char x, char y) => (char)Math.Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static char INumberBase<char>.MinMagnitudeNumber(char x, char y) => (char)Math.Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static bool INumberBase<char>.TryCreate<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<char>.TryConvertToTruncating<TOther>(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<char>.Parse(string s, NumberStyles style, IFormatProvider? provider) => Parse(s); - - static char INumberBase<char>.Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider) - { - if (s.Length != 1) - { - throw new FormatException(SR.Format_NeedSingleChar); - } - return s[0]; - } - static bool INumberBase<char>.TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out char result) => TryParse(s, out result); static bool INumberBase<char>.TryParse(ReadOnlySpan<char> 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 1fea9eba514..fdad839460d 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 @@ namespace System return new decimal(in value, value._flags & ~SignMask); } - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> public static bool IsCanonical(decimal value) { @@ -1711,111 +1467,305 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static decimal INumberBase<decimal>.MinMagnitudeNumber(decimal x, decimal y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<decimal>.TryConvertFromChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out decimal result) + static bool INumberBase<decimal>.TryConvertFromSaturating<TOther>(TOther value, out decimal result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<decimal>.TryConvertFromTruncating<TOther>(TOther value, out decimal result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out decimal result) where TOther : INumberBase<TOther> { + // 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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<decimal>.TryConvertToChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<decimal>.TryConvertToSaturating<TOther>(decimal value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<decimal>.TryConvertToTruncating<TOther>(decimal value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + private static bool TryConvertTo<TOther>(decimal value, [NotNullWhen(true)] out TOther result) + where TOther : INumberBase<TOther> + { + // 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 a84a966f9c5..1655435fbea 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static double Abs(double value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<double>.IsCanonical(double value) => true; @@ -1186,13 +1094,258 @@ namespace System return y; } - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<double>.TryConvertFromChecked<TOther>(TOther value, out double result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<double>.TryConvertFromSaturating<TOther>(TOther value, out double result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<double>.TryConvertFromTruncating<TOther>(TOther value, out double result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out double result) + where TOther : INumberBase<TOther> + { + // 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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out double result) + static bool INumberBase<double>.TryConvertToChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<double>.TryConvertToSaturating<TOther>(double value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<double>.TryConvertToTruncating<TOther>(double value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + private static bool TryConvertTo<TOther>(double value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase<TOther> { - 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 782abe963f7..059299f5eff 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 @@ namespace System 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) + /// <summary>Explicitly converts a <see cref="char" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(char value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="decimal" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(decimal value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="double" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + 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) + /// <summary>Explicitly converts a <see cref="short" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(short value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="int" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(int value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="long" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(long value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="System.IntPtr" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static explicit operator Half(nint value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="float" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + 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) + /// <summary>Explicitly converts a <see cref="ushort" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + [CLSCompliant(false)] + public static explicit operator Half(ushort value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="uint" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + [CLSCompliant(false)] + public static explicit operator Half(uint value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="ulong" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + [CLSCompliant(false)] + public static explicit operator Half(ulong value) => (Half)(float)value; + + /// <summary>Explicitly converts a <see cref="System.UIntPtr" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + [CLSCompliant(false)] + public static explicit operator Half(nuint value) => (Half)(float)value; + + // + // Explicit Convert From Half + // + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="byte" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="byte" /> value.</returns> + public static explicit operator byte(Half value) => (byte)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="byte" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="byte" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="byte" />.</exception> + public static explicit operator checked byte(Half value) => checked((byte)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="char" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="char" /> value.</returns> + public static explicit operator char(Half value) => (char)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="char" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="char" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="char" />.</exception> + public static explicit operator checked char(Half value) => checked((char)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="decimal" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="decimal" /> value.</returns> + public static explicit operator decimal(Half value) => (decimal)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="short" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="short" /> value.</returns> + public static explicit operator short(Half value) => (short)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="short" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="short" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="short" />.</exception> + public static explicit operator checked short(Half value) => checked((short)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="int" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="int" /> value.</returns> + public static explicit operator int(Half value) => (int)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="int" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="int" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="int" />.</exception> + public static explicit operator checked int(Half value) => checked((int)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="long" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="long" /> value.</returns> + public static explicit operator long(Half value) => (long)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="long" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="long" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="long" />.</exception> + public static explicit operator checked long(Half value) => checked((long)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="Int128"/>.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a 128-bit signed integer.</returns> + public static explicit operator Int128(Half value) => (Int128)(double)(value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="Int128"/>, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a 128-bit signed integer.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="Int128" />.</exception> + public static explicit operator checked Int128(Half value) => checked((Int128)(double)(value)); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="IntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="IntPtr" /> value.</returns> + public static explicit operator nint(Half value) => (nint)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="IntPtr" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="IntPtr" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="IntPtr" />.</exception> + public static explicit operator checked nint(Half value) => checked((nint)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="sbyte" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="sbyte" /> value.</returns> + [CLSCompliant(false)] + public static explicit operator sbyte(Half value) => (sbyte)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="sbyte" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="sbyte" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="sbyte" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked sbyte(Half value) => checked((sbyte)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="ushort" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ushort" /> value.</returns> + [CLSCompliant(false)] + public static explicit operator ushort(Half value) => (ushort)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="ushort" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ushort" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="ushort" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked ushort(Half value) => checked((ushort)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="uint" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="uint" /> value.</returns> + [CLSCompliant(false)] + public static explicit operator uint(Half value) => (uint)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="uint" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="uint" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="uint" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked uint(Half value) => checked((uint)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="ulong" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ulong" /> value.</returns> + [CLSCompliant(false)] + public static explicit operator ulong(Half value) => (ulong)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="ulong" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ulong" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="ulong" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked ulong(Half value) => checked((ulong)(float)value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="UInt128"/>.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a 128-bit unsigned integer.</returns> + [CLSCompliant(false)] + public static explicit operator UInt128(Half value) => (UInt128)(double)(value); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="UInt128"/>, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a 128-bit unsigned integer.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="UInt128" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked UInt128(Half value) => checked((UInt128)(double)(value)); + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="UIntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UIntPtr" /> value.</returns> + [CLSCompliant(false)] + public static explicit operator nuint(Half value) => (nuint)(float)value; + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="UIntPtr" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UIntPtr" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="UIntPtr" />.</exception> + [CLSCompliant(false)] + public static explicit operator checked nuint(Half value) => checked((nuint)(float)value); + + // + // Implicit Convert To Half + // + + /// <summary>Implicitly converts a <see cref="byte" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + public static implicit operator Half(byte value) => (Half)(float)value; + + /// <summary>Implicitly converts a <see cref="sbyte" /> value to its nearest representable half-precision floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable half-precision floating-point value.</returns> + [CLSCompliant(false)] + public static implicit operator Half(sbyte value) => (Half)(float)value; + + // + // Implicit Convert From Half (actually explicit due to back-compat) + // + + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="double" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="double" /> value.</returns> + public static explicit operator double(Half value) { bool sign = IsNegative(value); int exp = value.BiasedExponent; @@ -606,25 +853,28 @@ namespace System { 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) + /// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="float" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="float" /> value.</returns> + public static explicit operator float(Half value) { bool sign = IsNegative(value); int exp = value.BiasedExponent; @@ -634,22 +884,22 @@ namespace System { 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 @@ namespace System 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static Half Abs(Half value) => (Half)MathF.Abs((float)value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Half CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<Half>.IsCanonical(Half value) => true; @@ -1378,13 +1536,251 @@ namespace System return y; } - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Half>.TryConvertFromChecked<TOther>(TOther value, out Half result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out Half result) + static bool INumberBase<Half>.TryConvertFromSaturating<TOther>(TOther value, out Half result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Half>.TryConvertFromTruncating<TOther>(TOther value, out Half result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out Half result) where TOther : INumberBase<TOther> { - 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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Half>.TryConvertToChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Half>.TryConvertToSaturating<TOther>(Half value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Half>.TryConvertToTruncating<TOther>(Half value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + private static bool TryConvertTo<TOther>(Half value, [NotNullWhen(true)] out TOther result) + where TOther : INumberBase<TOther> + { + // 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 56919478ccc..31fdfd22ebf 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 @@ namespace System } } - /// <summary>Explicitly converts a <see cref="Half" /> value to a 128-bit signed integer.</summary> - /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to a 128-bit signed integer.</returns> - public static explicit operator Int128(Half value) => (Int128)(double)(value); - - /// <summary>Explicitly converts a <see cref="Half" /> value to a 128-bit signed integer, throwing an overflow exception for any values that fall outside the representable range.</summary> - /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to a 128-bit signed integer.</returns> - /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="Int128" />.</exception> - public static explicit operator checked Int128(Half value) => checked((Int128)(double)(value)); - /// <summary>Explicitly converts a <see cref="float" /> value to a 128-bit signed integer.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to a 128-bit signed integer.</returns> @@ -1286,222 +1275,6 @@ namespace System return value; } - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int128 CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<Int128>.IsCanonical(Int128 value) => true; @@ -1639,114 +1412,423 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static Int128 INumberBase<Int128>.MinMagnitudeNumber(Int128 x, Int128 y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out Int128 result) - where TOther : INumberBase<TOther> + static bool INumberBase<Int128>.TryConvertFromChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Int128>.TryConvertFromSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Int128>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Int128>.TryConvertToChecked<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Int128>.TryConvertToSaturating<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Int128>.TryConvertToTruncating<TOther>(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 0456102d42d..75025b7a597 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static short Abs(short value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<short>.IsCanonical(short value) => true; @@ -935,173 +714,421 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static short INumberBase<short>.MinMagnitudeNumber(short x, short y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out short result) - where TOther : INumberBase<TOther> + static bool INumberBase<short>.TryConvertFromChecked<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<short>.TryConvertFromSaturating<TOther>(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; + } + } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<short>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<short>.TryConvertToChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<short>.TryConvertToSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<short>.TryConvertToTruncating<TOther>(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 291030805a1..b40fedc2636 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static int Abs(int value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<int>.IsCanonical(int value) => true; @@ -923,149 +706,422 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static int INumberBase<int>.MinMagnitudeNumber(int x, int y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out int result) - where TOther : INumberBase<TOther> + static bool INumberBase<int>.TryConvertFromChecked<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<int>.TryConvertFromSaturating<TOther>(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; + } + } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<int>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<int>.TryConvertToChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<int>.TryConvertToSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<int>.TryConvertToTruncating<TOther>(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 34b2add1462..0c7fa4a26d3 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static long Abs(long value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<long>.IsCanonical(long value) => true; @@ -905,125 +693,428 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static long INumberBase<long>.MinMagnitudeNumber(long x, long y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out long result) - where TOther : INumberBase<TOther> + static bool INumberBase<long>.TryConvertFromChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<long>.TryConvertFromSaturating<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<long>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<long>.TryConvertToChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<long>.TryConvertToSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<long>.TryConvertToTruncating<TOther>(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 36de25a6061..9d3e923096b 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static nint Abs(nint value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nint CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<nint>.IsCanonical(nint value) => true; @@ -881,141 +666,422 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static nint INumberBase<nint>.MinMagnitudeNumber(nint x, nint y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out nint result) - where TOther : INumberBase<TOther> + static bool INumberBase<nint>.TryConvertFromChecked<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nint>.TryConvertFromSaturating<TOther>(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; + } + } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nint>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nint>.TryConvertToChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nint>.TryConvertToSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nint>.TryConvertToTruncating<TOther>(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 d0aef03aa39..17ec3897a4f 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 @@ namespace System // 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 @@ namespace System } else { - result = (Half)0; + result = Half.Zero; return false; } } @@ -2565,7 +2565,7 @@ namespace System } 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 c38edf1ca3b..cefd019a9aa 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 @@ namespace System.Numerics /// <returns>An instance of <typeparamref name="TSelf" /> created from <paramref name="value" />.</returns> /// <exception cref="NotSupportedException"><typeparamref name="TOther" /> is not supported.</exception> /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <typeparamref name="TSelf" />.</exception> - static abstract TSelf CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther>; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateChecked<TOther>(TOther value) + where TOther : INumberBase<TOther> + { + 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; + } /// <summary>Creates an instance of the current type from a value, saturating any values that fall outside the representable range of the current type.</summary> /// <typeparam name="TOther">The type of <paramref name="value" />.</typeparam> /// <param name="value">The value which is used to create the instance of <typeparamref name="TSelf" />.</param> /// <returns>An instance of <typeparamref name="TSelf" /> created from <paramref name="value" />, saturating if <paramref name="value" /> falls outside the representable range of <typeparamref name="TSelf" />.</returns> /// <exception cref="NotSupportedException"><typeparamref name="TOther" /> is not supported.</exception> - static abstract TSelf CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther>; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateSaturating<TOther>(TOther value) + where TOther : INumberBase<TOther> + { + 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; + } /// <summary>Creates an instance of the current type from a value, truncating any values that fall outside the representable range of the current type.</summary> /// <typeparam name="TOther">The type of <paramref name="value" />.</typeparam> /// <param name="value">The value which is used to create the instance of <typeparamref name="TSelf" />.</param> /// <returns>An instance of <typeparamref name="TSelf" /> created from <paramref name="value" />, truncating if <paramref name="value" /> falls outside the representable range of <typeparamref name="TSelf" />.</returns> /// <exception cref="NotSupportedException"><typeparamref name="TOther" /> is not supported.</exception> - static abstract TSelf CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther>; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual TSelf CreateTruncating<TOther>(TOther value) + where TOther : INumberBase<TOther> + { + 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; + } /// <summary>Determines if a value is in its canonical representation.</summary> /// <param name="value">The value to be checked.</param> @@ -215,13 +261,54 @@ namespace System.Numerics /// <exception cref="OverflowException"><paramref name="s" /> is not representable by <typeparamref name="TSelf" />.</exception> static abstract TSelf Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider); - /// <summary>Tries to create an instance of the current type from a value.</summary> + /// <summary>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.</summary> /// <typeparam name="TOther">The type of <paramref name="value" />.</typeparam> /// <param name="value">The value which is used to create the instance of <typeparamref name="TSelf" />.</param> - /// <param name="result">On return, contains the result of succesfully creating an instance of <typeparamref name="TSelf" /> from <paramref name="value" /> or an undefined value on failure.</param> - /// <returns><c>true</c> if <paramref name="value" /> an instance of the current type was succesfully created from <paramref name="value" />; otherwise, <c>false</c>.</returns> - /// <exception cref="NotSupportedException"><typeparamref name="TOther" /> is not supported.</exception> - static abstract bool TryCreate<TOther>(TOther value, out TSelf result) + /// <param name="result">On return, contains an instance of <typeparamref name="TSelf" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <typeparamref name="TSelf" />.</exception> + protected static abstract bool TryConvertFromChecked<TOther>(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase<TOther>; + + /// <summary>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.</summary> + /// <typeparam name="TOther">The type of <paramref name="value" />.</typeparam> + /// <param name="value">The value which is used to create the instance of <typeparamref name="TSelf" />.</param> + /// <param name="result">On return, contains an instance of <typeparamref name="TSelf" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + protected static abstract bool TryConvertFromSaturating<TOther>(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase<TOther>; + + /// <summary>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.</summary> + /// <typeparam name="TOther">The type of <paramref name="value" />.</typeparam> + /// <param name="value">The value which is used to create the instance of <typeparamref name="TSelf" />.</param> + /// <param name="result">On return, contains an instance of <typeparamref name="TSelf" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + protected static abstract bool TryConvertFromTruncating<TOther>(TOther value, [NotNullWhen(true)] out TSelf? result) + where TOther : INumberBase<TOther>; + + /// <summary>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.</summary> + /// <typeparam name="TOther">The type to which <paramref name="value" /> should be converted.</typeparam> + /// <param name="value">The value which is used to create the instance of <typeparamref name="TOther" />.</param> + /// <param name="result">On return, contains an instance of <typeparamref name="TOther" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <typeparamref name="TOther" />.</exception> + protected static abstract bool TryConvertToChecked<TOther>(TSelf value, [NotNullWhen(true)] out TOther? result) + where TOther : INumberBase<TOther>; + + /// <summary>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.</summary> + /// <typeparam name="TOther">The type to which <paramref name="value" /> should be converted.</typeparam> + /// <param name="value">The value which is used to create the instance of <typeparamref name="TOther" />.</param> + /// <param name="result">On return, contains an instance of <typeparamref name="TOther" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + protected static abstract bool TryConvertToSaturating<TOther>(TSelf value, [NotNullWhen(true)] out TOther? result) + where TOther : INumberBase<TOther>; + + /// <summary>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.</summary> + /// <typeparam name="TOther">The type to which <paramref name="value" /> should be converted.</typeparam> + /// <param name="value">The value which is used to create the instance of <typeparamref name="TOther" />.</param> + /// <param name="result">On return, contains an instance of <typeparamref name="TOther" /> converted from <paramref name="value" />.</param> + /// <returns><c>false</c> if <typeparamref name="TOther" /> is not supported; otherwise, <c>true</c>.</returns> + protected static abstract bool TryConvertToTruncating<TOther>(TSelf value, [NotNullWhen(true)] out TOther? result) where TOther : INumberBase<TOther>; /// <summary>Tries to parses a string into a value.</summary> 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 97f3a349c28..f197cbc6f96 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 @@ namespace System.Runtime.InteropServices [NonVersionable] public static explicit operator byte(NFloat value) => (byte)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="byte" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="byte" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="byte" />.</exception> + [NonVersionable] + public static explicit operator checked byte(NFloat value) => checked((byte)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="char" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="char" /> value.</returns> [NonVersionable] public static explicit operator char(NFloat value) => (char)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="char" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="char" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="char" />.</exception> + [NonVersionable] + public static explicit operator checked char(NFloat value) => checked((char)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="decimal" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="decimal" /> value.</returns> [NonVersionable] public static explicit operator decimal(NFloat value) => (decimal)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="Half" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="Half" /> value.</returns> + [NonVersionable] + public static explicit operator Half(NFloat value) => (Half)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="short" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="short" /> value.</returns> [NonVersionable] public static explicit operator short(NFloat value) => (short)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="short" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="short" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="short" />.</exception> + [NonVersionable] + public static explicit operator checked short(NFloat value) => checked((short)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="int" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="int" /> value.</returns> [NonVersionable] public static explicit operator int(NFloat value) => (int)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="int" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="int" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="int" />.</exception> + [NonVersionable] + public static explicit operator checked int(NFloat value) => checked((int)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="long" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="long" /> value.</returns> [NonVersionable] public static explicit operator long(NFloat value) => (long)(value._value); - /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="System.IntPtr" /> value.</summary> + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="long" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to its nearest representable <see cref="System.IntPtr" /> value.</returns> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="long" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="long" />.</exception> + [NonVersionable] + public static explicit operator checked long(NFloat value) => checked((long)(value._value)); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="Int128" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="Int128" /> value.</returns> + [NonVersionable] + public static explicit operator Int128(NFloat value) => (Int128)(value._value); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="Int128" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="Int128" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="Int128" />.</exception> + [NonVersionable] + public static explicit operator checked Int128(NFloat value) => checked((Int128)(value._value)); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="IntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="IntPtr" /> value.</returns> [NonVersionable] public static explicit operator nint(NFloat value) => (nint)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="IntPtr" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="IntPtr" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="IntPtr" />.</exception> + [NonVersionable] + public static explicit operator checked nint(NFloat value) => checked((nint)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="sbyte" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="sbyte" /> value.</returns> @@ -296,6 +357,14 @@ namespace System.Runtime.InteropServices [CLSCompliant(false)] public static explicit operator sbyte(NFloat value) => (sbyte)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="sbyte" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="sbyte" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="sbyte" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked sbyte(NFloat value) => checked((sbyte)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="float" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="float" /> value.</returns> @@ -309,6 +378,14 @@ namespace System.Runtime.InteropServices [CLSCompliant(false)] public static explicit operator ushort(NFloat value) => (ushort)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="ushort" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ushort" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="ushort" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked ushort(NFloat value) => checked((ushort)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="uint" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="uint" /> value.</returns> @@ -316,6 +393,14 @@ namespace System.Runtime.InteropServices [CLSCompliant(false)] public static explicit operator uint(NFloat value) => (uint)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="uint" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="uint" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="uint" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked uint(NFloat value) => checked((uint)(value._value)); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="ulong" /> value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ulong" /> value.</returns> @@ -323,13 +408,44 @@ namespace System.Runtime.InteropServices [CLSCompliant(false)] public static explicit operator ulong(NFloat value) => (ulong)(value._value); - /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="System.UIntPtr" /> value.</summary> + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="ulong" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to its nearest representable <see cref="System.UIntPtr" /> value.</returns> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="ulong" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="ulong" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked ulong(NFloat value) => checked((ulong)(value._value)); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="UInt128" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UInt128" /> value.</returns> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator UInt128(NFloat value) => (UInt128)(value._value); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="UInt128" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UInt128" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="UInt128" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked UInt128(NFloat value) => checked((UInt128)(value._value)); + + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="UIntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UIntPtr" /> value.</returns> [NonVersionable] [CLSCompliant(false)] public static explicit operator nuint(NFloat value) => (nuint)(value._value); + /// <summary>Explicitly converts a native-sized floating-point value to its nearest representable <see cref="UIntPtr" /> value, throwing an overflow exception for any values that fall outside the representable range.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable <see cref="UIntPtr" /> value.</returns> + /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="UIntPtr" />.</exception> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator checked nuint(NFloat value) => checked((nuint)(value._value)); + // // Implicit Convert To NFloat // @@ -346,6 +462,12 @@ namespace System.Runtime.InteropServices [NonVersionable] public static implicit operator NFloat(char value) => new NFloat((NativeType)value); + /// <summary>Implicitly converts a <see cref="Half" /> value to its nearest representable native-sized floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> + [NonVersionable] + public static implicit operator NFloat(Half value) => (NFloat)(float)value; + /// <summary>Implicitly converts a <see cref="short" /> value to its nearest representable native-sized floating-point value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> @@ -364,6 +486,20 @@ namespace System.Runtime.InteropServices [NonVersionable] public static implicit operator NFloat(long value) => new NFloat((NativeType)value); + /// <summary>Explicitly converts a <see cref="Int128" /> to its nearest representable native-sized floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> + [NonVersionable] + public static explicit operator NFloat(Int128 value) + { + if (Int128.IsNegative(value)) + { + value = -value; + return -(NFloat)(UInt128)(value); + } + return (NFloat)(UInt128)(value); + } + /// <summary>Implicitly converts a <see cref="System.IntPtr" /> value to its nearest representable native-sized floating-point value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> @@ -404,6 +540,13 @@ namespace System.Runtime.InteropServices [CLSCompliant(false)] public static implicit operator NFloat(ulong value) => new NFloat((NativeType)value); + /// <summary>Explicitly converts <see cref="UInt128"/> to its nearest representable native-sized floating-point value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> + [NonVersionable] + [CLSCompliant(false)] + public static explicit operator NFloat(UInt128 value) => (NFloat)(double)(value); + /// <summary>Implicitly converts a <see cref="System.UIntPtr" /> value to its nearest representable native-sized floating-point value.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to its nearest representable native-sized floating-point value.</returns> @@ -1137,140 +1280,438 @@ namespace System.Runtime.InteropServices /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static NFloat Abs(NFloat value) => new NFloat(NativeType.Abs(value._value)); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<NFloat>.IsCanonical(NFloat value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<NFloat>.IsComplexNumber(NFloat value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(NFloat value) => NativeType.IsEvenInteger(value._value); + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<NFloat>.IsImaginaryNumber(NFloat value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + public static bool IsInteger(NFloat value) => NativeType.IsInteger(value._value); + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(NFloat value) => NativeType.IsOddInteger(value._value); + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + public static bool IsPositive(NFloat value) => NativeType.IsPositive(value._value); + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + public static bool IsRealNumber(NFloat value) => NativeType.IsRealNumber(value._value); + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<NFloat>.IsZero(NFloat value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + public static NFloat MaxMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitude(x._value, y._value)); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + public static NFloat MaxMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitudeNumber(x._value, y._value)); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + public static NFloat MinMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitude(x._value, y._value)); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + public static NFloat MinMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitudeNumber(x._value, y._value)); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<NFloat>.TryConvertFromChecked<TOther>(TOther value, out NFloat result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<NFloat>.TryConvertFromSaturating<TOther>(TOther value, out NFloat result) { - return CreateSaturating(value); + return TryConvertFrom<TOther>(value, out result); } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateSaturating<TOther>(TOther value) + static bool INumberBase<NFloat>.TryConvertFromTruncating<TOther>(TOther value, out NFloat result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out NFloat result) where TOther : INumberBase<TOther> { 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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static NFloat CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<NFloat>.TryConvertToChecked<TOther>(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; + } } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<NFloat>.IsCanonical(NFloat value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<NFloat>.IsComplexNumber(NFloat value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(NFloat value) => NativeType.IsEvenInteger(value._value); - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<NFloat>.IsImaginaryNumber(NFloat value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - public static bool IsInteger(NFloat value) => NativeType.IsInteger(value._value); - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(NFloat value) => NativeType.IsOddInteger(value._value); - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - public static bool IsPositive(NFloat value) => NativeType.IsPositive(value._value); - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - public static bool IsRealNumber(NFloat value) => NativeType.IsRealNumber(value._value); - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<NFloat>.IsZero(NFloat value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - public static NFloat MaxMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitude(x._value, y._value)); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - public static NFloat MaxMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxMagnitudeNumber(x._value, y._value)); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - public static NFloat MinMagnitude(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitude(x._value, y._value)); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - public static NFloat MinMagnitudeNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinMagnitudeNumber(x._value, y._value)); + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<NFloat>.TryConvertToSaturating<TOther>(NFloat value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out NFloat result) + static bool INumberBase<NFloat>.TryConvertToTruncating<TOther>(NFloat value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + private static bool TryConvertTo<TOther>(NFloat value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase<TOther> { - 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 ff3edb4dd7e..ac88c897ae9 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static sbyte Abs(sbyte value) => Math.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<sbyte>.IsCanonical(sbyte value) => true; @@ -945,189 +721,421 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> static sbyte INumberBase<sbyte>.MinMagnitudeNumber(sbyte x, sbyte y) => MinMagnitude(x, y); - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out sbyte result) - where TOther : INumberBase<TOther> + static bool INumberBase<sbyte>.TryConvertFromChecked<TOther>(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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<sbyte>.TryConvertFromSaturating<TOther>(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; + } + } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<sbyte>.TryConvertFromTruncating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<sbyte>.TryConvertToChecked<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<sbyte>.TryConvertToSaturating<TOther>(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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<sbyte>.TryConvertToTruncating<TOther>(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 2ff1aad7fcf..96e413d938f 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> public static float Abs(float value) => MathF.Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - return CreateSaturating(value); - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<float>.IsCanonical(float value) => true; @@ -1169,13 +1077,258 @@ namespace System return y; } - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<float>.TryConvertFromChecked<TOther>(TOther value, out float result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<float>.TryConvertFromSaturating<TOther>(TOther value, out float result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<float>.TryConvertFromTruncating<TOther>(TOther value, out float result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out float result) + where TOther : INumberBase<TOther> + { + // 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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<float>.TryConvertToChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out float result) + static bool INumberBase<float>.TryConvertToSaturating<TOther>(float value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<float>.TryConvertToTruncating<TOther>(float value, [NotNullWhen(true)] out TOther result) + { + return TryConvertTo<TOther>(value, out result); + } + + private static bool TryConvertTo<TOther>(float value, [NotNullWhen(true)] out TOther result) where TOther : INumberBase<TOther> { - 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 90b370f61ea..b2b9771ba56 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 @@ namespace System } } - /// <summary>Explicitly converts a <see cref="Half" /> value to a 128-bit unsigned integer.</summary> - /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to a 128-bit unsigned integer.</returns> - public static explicit operator UInt128(Half value) => (UInt128)(double)(value); - - /// <summary>Explicitly converts a <see cref="Half" /> value to a 128-bit unsigned integer, throwing an overflow exception for any values that fall outside the representable range.</summary> - /// <param name="value">The value to convert.</param> - /// <returns><paramref name="value" /> converted to a 128-bit unsigned integer.</returns> - /// <exception cref="OverflowException"><paramref name="value" /> is not representable by <see cref="UInt128" />.</exception> - public static explicit operator checked UInt128(Half value) => checked((UInt128)(double)(value)); - /// <summary>Explicitly converts a <see cref="short" /> value to a 128-bit unsigned integer.</summary> /// <param name="value">The value to convert.</param> /// <returns><paramref name="value" /> converted to a 128-bit unsigned integer.</returns> @@ -1344,448 +1333,479 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static UInt128 INumberBase<UInt128>.Abs(UInt128 value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<UInt128>.IsCanonical(UInt128 value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<UInt128>.IsComplexNumber(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(UInt128 value) => (value._lower & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<UInt128>.IsFinite(UInt128 value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<UInt128>.IsImaginaryNumber(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<UInt128>.IsInfinity(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<UInt128>.IsInteger(UInt128 value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<UInt128>.IsNaN(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<UInt128>.IsNegative(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<UInt128>.IsNegativeInfinity(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<UInt128>.IsNormal(UInt128 value) => value != 0U; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(UInt128 value) => (value._lower & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<UInt128>.IsPositive(UInt128 value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<UInt128>.IsPositiveInfinity(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<UInt128>.IsRealNumber(UInt128 value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<UInt128>.IsSubnormal(UInt128 value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<UInt128>.IsZero(UInt128 value) => (value == 0U); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static UInt128 INumberBase<UInt128>.MaxMagnitude(UInt128 x, UInt128 y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static UInt128 INumberBase<UInt128>.MaxMagnitudeNumber(UInt128 x, UInt128 y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static UInt128 INumberBase<UInt128>.MinMagnitude(UInt128 x, UInt128 y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static UInt128 INumberBase<UInt128>.MinMagnitudeNumber(UInt128 x, UInt128 y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<UInt128>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<UInt128>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<UInt128>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt128 CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<UInt128>.TryConvertToChecked<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<UInt128>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<UInt128>.IsCanonical(UInt128 value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<UInt128>.IsComplexNumber(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(UInt128 value) => (value._lower & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<UInt128>.IsFinite(UInt128 value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<UInt128>.IsImaginaryNumber(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<UInt128>.IsInfinity(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<UInt128>.IsInteger(UInt128 value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<UInt128>.IsNaN(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<UInt128>.IsNegative(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<UInt128>.IsNegativeInfinity(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<UInt128>.IsNormal(UInt128 value) => value != 0U; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(UInt128 value) => (value._lower & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<UInt128>.IsPositive(UInt128 value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<UInt128>.IsPositiveInfinity(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<UInt128>.IsRealNumber(UInt128 value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<UInt128>.IsSubnormal(UInt128 value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<UInt128>.IsZero(UInt128 value) => (value == 0U); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static UInt128 INumberBase<UInt128>.MaxMagnitude(UInt128 x, UInt128 y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static UInt128 INumberBase<UInt128>.MaxMagnitudeNumber(UInt128 x, UInt128 y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static UInt128 INumberBase<UInt128>.MinMagnitude(UInt128 x, UInt128 y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static UInt128 INumberBase<UInt128>.MinMagnitudeNumber(UInt128 x, UInt128 y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out UInt128 result) - where TOther : INumberBase<TOther> - { - 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; - } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<UInt128>.TryConvertToTruncating<TOther>(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 97b6e6b7a88..3ef0feff7a9 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static ushort INumberBase<ushort>.Abs(ushort value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<ushort>.IsCanonical(ushort value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<ushort>.IsComplexNumber(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(ushort value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<ushort>.IsFinite(ushort value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<ushort>.IsImaginaryNumber(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<ushort>.IsInfinity(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<ushort>.IsInteger(ushort value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<ushort>.IsNaN(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<ushort>.IsNegative(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<ushort>.IsNegativeInfinity(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<ushort>.IsNormal(ushort value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(ushort value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<ushort>.IsPositive(ushort value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<ushort>.IsPositiveInfinity(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<ushort>.IsRealNumber(ushort value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<ushort>.IsSubnormal(ushort value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<ushort>.IsZero(ushort value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static ushort INumberBase<ushort>.MaxMagnitude(ushort x, ushort y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static ushort INumberBase<ushort>.MaxMagnitudeNumber(ushort x, ushort y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static ushort INumberBase<ushort>.MinMagnitude(ushort x, ushort y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static ushort INumberBase<ushort>.MinMagnitudeNumber(ushort x, ushort y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ushort>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ushort>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ushort>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ushort>.TryConvertToChecked<TOther>(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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ushort>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<ushort>.IsCanonical(ushort value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<ushort>.IsComplexNumber(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(ushort value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<ushort>.IsFinite(ushort value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<ushort>.IsImaginaryNumber(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<ushort>.IsInfinity(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<ushort>.IsInteger(ushort value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<ushort>.IsNaN(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<ushort>.IsNegative(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<ushort>.IsNegativeInfinity(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<ushort>.IsNormal(ushort value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(ushort value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<ushort>.IsPositive(ushort value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<ushort>.IsPositiveInfinity(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<ushort>.IsRealNumber(ushort value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<ushort>.IsSubnormal(ushort value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<ushort>.IsZero(ushort value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static ushort INumberBase<ushort>.MaxMagnitude(ushort x, ushort y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static ushort INumberBase<ushort>.MaxMagnitudeNumber(ushort x, ushort y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static ushort INumberBase<ushort>.MinMagnitude(ushort x, ushort y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static ushort INumberBase<ushort>.MinMagnitudeNumber(ushort x, ushort y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out ushort result) - where TOther : INumberBase<TOther> - { - 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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ushort>.TryConvertToTruncating<TOther>(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 eddab867b02..93c27f43d5d 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static uint INumberBase<uint>.Abs(uint value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<uint>.IsCanonical(uint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<uint>.IsComplexNumber(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(uint value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<uint>.IsFinite(uint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<uint>.IsImaginaryNumber(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<uint>.IsInfinity(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<uint>.IsInteger(uint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<uint>.IsNaN(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<uint>.IsNegative(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<uint>.IsNegativeInfinity(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<uint>.IsNormal(uint value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(uint value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<uint>.IsPositive(uint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<uint>.IsPositiveInfinity(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<uint>.IsRealNumber(uint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<uint>.IsSubnormal(uint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<uint>.IsZero(uint value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static uint INumberBase<uint>.MaxMagnitude(uint x, uint y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static uint INumberBase<uint>.MaxMagnitudeNumber(uint x, uint y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static uint INumberBase<uint>.MinMagnitude(uint x, uint y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static uint INumberBase<uint>.MinMagnitudeNumber(uint x, uint y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<uint>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<uint>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<uint>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<uint>.TryConvertToChecked<TOther>(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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<uint>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<uint>.IsCanonical(uint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<uint>.IsComplexNumber(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(uint value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<uint>.IsFinite(uint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<uint>.IsImaginaryNumber(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<uint>.IsInfinity(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<uint>.IsInteger(uint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<uint>.IsNaN(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<uint>.IsNegative(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<uint>.IsNegativeInfinity(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<uint>.IsNormal(uint value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(uint value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<uint>.IsPositive(uint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<uint>.IsPositiveInfinity(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<uint>.IsRealNumber(uint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<uint>.IsSubnormal(uint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<uint>.IsZero(uint value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static uint INumberBase<uint>.MaxMagnitude(uint x, uint y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static uint INumberBase<uint>.MaxMagnitudeNumber(uint x, uint y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static uint INumberBase<uint>.MinMagnitude(uint x, uint y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static uint INumberBase<uint>.MinMagnitudeNumber(uint x, uint y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out uint result) - where TOther : INumberBase<TOther> - { - 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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<uint>.TryConvertToTruncating<TOther>(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 48607b8819f..928163fa2a8 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static ulong INumberBase<ulong>.Abs(ulong value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<ulong>.IsCanonical(ulong value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<ulong>.IsComplexNumber(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(ulong value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<ulong>.IsFinite(ulong value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<ulong>.IsImaginaryNumber(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<ulong>.IsInfinity(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<ulong>.IsInteger(ulong value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<ulong>.IsNaN(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<ulong>.IsNegative(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<ulong>.IsNegativeInfinity(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<ulong>.IsNormal(ulong value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(ulong value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<ulong>.IsPositive(ulong value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<ulong>.IsPositiveInfinity(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<ulong>.IsRealNumber(ulong value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<ulong>.IsSubnormal(ulong value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<ulong>.IsZero(ulong value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static ulong INumberBase<ulong>.MaxMagnitude(ulong x, ulong y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static ulong INumberBase<ulong>.MaxMagnitudeNumber(ulong x, ulong y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static ulong INumberBase<ulong>.MinMagnitude(ulong x, ulong y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static ulong INumberBase<ulong>.MinMagnitudeNumber(ulong x, ulong y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ulong>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ulong>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ulong>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<ulong>.TryConvertToChecked<TOther>(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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ulong>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<ulong>.IsCanonical(ulong value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<ulong>.IsComplexNumber(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(ulong value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<ulong>.IsFinite(ulong value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<ulong>.IsImaginaryNumber(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<ulong>.IsInfinity(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<ulong>.IsInteger(ulong value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<ulong>.IsNaN(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<ulong>.IsNegative(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<ulong>.IsNegativeInfinity(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<ulong>.IsNormal(ulong value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(ulong value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<ulong>.IsPositive(ulong value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<ulong>.IsPositiveInfinity(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<ulong>.IsRealNumber(ulong value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<ulong>.IsSubnormal(ulong value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<ulong>.IsZero(ulong value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static ulong INumberBase<ulong>.MaxMagnitude(ulong x, ulong y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static ulong INumberBase<ulong>.MaxMagnitudeNumber(ulong x, ulong y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static ulong INumberBase<ulong>.MinMagnitude(ulong x, ulong y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static ulong INumberBase<ulong>.MinMagnitudeNumber(ulong x, ulong y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out ulong result) - where TOther : INumberBase<TOther> - { - 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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<ulong>.TryConvertToTruncating<TOther>(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 4795ef4df67..48ef6b8103f 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 @@ namespace System /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static nuint INumberBase<nuint>.Abs(nuint value) => value; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<nuint>.IsCanonical(nuint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<nuint>.IsComplexNumber(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(nuint value) => (value & 1) == 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<nuint>.IsFinite(nuint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<nuint>.IsImaginaryNumber(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<nuint>.IsInfinity(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<nuint>.IsInteger(nuint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<nuint>.IsNaN(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + static bool INumberBase<nuint>.IsNegative(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<nuint>.IsNegativeInfinity(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<nuint>.IsNormal(nuint value) => value != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(nuint value) => (value & 1) != 0; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + static bool INumberBase<nuint>.IsPositive(nuint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<nuint>.IsPositiveInfinity(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<nuint>.IsRealNumber(nuint value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<nuint>.IsSubnormal(nuint value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<nuint>.IsZero(nuint value) => (value == 0); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + static nuint INumberBase<nuint>.MaxMagnitude(nuint x, nuint y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static nuint INumberBase<nuint>.MaxMagnitudeNumber(nuint x, nuint y) => Max(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + static nuint INumberBase<nuint>.MinMagnitude(nuint x, nuint y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static nuint INumberBase<nuint>.MinMagnitudeNumber(nuint x, nuint y) => Min(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<nuint>.TryConvertFromChecked<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<nuint>.TryConvertFromSaturating<TOther>(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)) + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nuint>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<nuint>.TryConvertToChecked<TOther>(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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nuint>.TryConvertToSaturating<TOther>(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; } - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<nuint>.IsCanonical(nuint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<nuint>.IsComplexNumber(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(nuint value) => (value & 1) == 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<nuint>.IsFinite(nuint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<nuint>.IsImaginaryNumber(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<nuint>.IsInfinity(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<nuint>.IsInteger(nuint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<nuint>.IsNaN(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - static bool INumberBase<nuint>.IsNegative(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<nuint>.IsNegativeInfinity(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<nuint>.IsNormal(nuint value) => value != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - public static bool IsOddInteger(nuint value) => (value & 1) != 0; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - static bool INumberBase<nuint>.IsPositive(nuint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<nuint>.IsPositiveInfinity(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<nuint>.IsRealNumber(nuint value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<nuint>.IsSubnormal(nuint value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<nuint>.IsZero(nuint value) => (value == 0); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - static nuint INumberBase<nuint>.MaxMagnitude(nuint x, nuint y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static nuint INumberBase<nuint>.MaxMagnitudeNumber(nuint x, nuint y) => Max(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - static nuint INumberBase<nuint>.MinMagnitude(nuint x, nuint y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static nuint INumberBase<nuint>.MinMagnitudeNumber(nuint x, nuint y) => Min(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out nuint result) - where TOther : INumberBase<TOther> - { - 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; + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<nuint>.TryConvertToTruncating<TOther>(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 7d59b44cdad..cbff7ff2612 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 @@ namespace System.Runtime.InteropServices 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Runtime.InteropServices.NFloat CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Runtime.InteropServices.NFloat CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System.Runtime.InteropServices 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 @@ namespace System.Runtime.InteropServices 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 @@ namespace System.Runtime.InteropServices 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 @@ namespace System.Runtime.InteropServices 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 @@ namespace System.Runtime.InteropServices static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.IsComplexNumber(System.Runtime.InteropServices.NFloat value) { throw null; } static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.IsImaginaryNumber(System.Runtime.InteropServices.NFloat value) { throw null; } static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.IsZero(System.Runtime.InteropServices.NFloat value) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertFromChecked<TOther>(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertFromSaturating<TOther>(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertFromTruncating<TOther>(TOther value, out System.Runtime.InteropServices.NFloat result) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertToChecked<TOther>(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertToSaturating<TOther>(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Runtime.InteropServices.NFloat>.TryConvertToTruncating<TOther>(System.Runtime.InteropServices.NFloat value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Runtime.InteropServices.NFloat System.Numerics.ISubtractionOperators<System.Runtime.InteropServices.NFloat, System.Runtime.InteropServices.NFloat, System.Runtime.InteropServices.NFloat>.operator checked -(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } static System.Runtime.InteropServices.NFloat System.Numerics.IUnaryNegationOperators<System.Runtime.InteropServices.NFloat, System.Runtime.InteropServices.NFloat>.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 @@ namespace System.Runtime.InteropServices 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>(TOther value, out System.Runtime.InteropServices.NFloat result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Runtime.InteropServices.NFloat result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> 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 657ccd9f4af..5216e69b0d1 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 @@ <Compile Include="System\Runtime\InteropServices\CallingConventionTests.cs" /> <Compile Include="System\Runtime\InteropServices\ClassInterfaceAttributeTests.cs" /> <Compile Include="System\Runtime\InteropServices\NativeMemoryTests.cs" /> - <Compile Include="System\Runtime\InteropServices\NFloatTests.cs" /> <Compile Include="System\Runtime\InteropServices\CULongTests.cs" /> <Compile Include="System\Runtime\InteropServices\CLongTests.cs" /> <Compile Include="System\Runtime\InteropServices\CoClassAttributeTests.cs" /> @@ -149,6 +148,7 @@ <Compile Include="System\Runtime\InteropServices\Marshal\StringMarshalingTests.cs" /> <Compile Include="System\Runtime\InteropServices\Marshal\StructureToPtrTests.cs" /> <Compile Include="System\Runtime\InteropServices\Marshal\UnsafeAddrOfPinnedArrayElementTests.cs" /> + <Compile Include="System\Runtime\InteropServices\NFloatTests.cs" /> <Compile Include="System\Runtime\InteropServices\ObjectiveC\MessageSendTests.cs" /> <Compile Include="System\Runtime\InteropServices\ObjectiveC\PendingExceptionTests.cs" /> <Compile Include="System\Runtime\InteropServices\ObjectiveC\LibObjC.cs" /> 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 3e842bd7ab1..00e3c9601ae 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 @@ -1533,6 +1534,105 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateChecked<decimal>(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateChecked<decimal>(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateChecked<double>(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateChecked<double>(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateChecked<double>(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateChecked<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateChecked<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateChecked<double>(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateChecked<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateChecked<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateChecked<double>(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateChecked<double>(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<double>(double.MaxValue)); + } + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper<NFloat>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateChecked<Half>(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper<NFloat>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<NFloat>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<NFloat>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<NFloat>.CreateChecked<Half>(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<NFloat>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<NFloat>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<NFloat>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + + [Fact] public static void CreateCheckedFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateChecked<short>(0x0000)); @@ -1581,6 +1681,25 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateChecked<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1602,6 +1721,34 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateChecked<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateChecked<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateChecked<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateChecked<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateChecked<sbyte>(0x00)); @@ -1612,6 +1759,32 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateChecked<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateChecked<float>(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateChecked<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateChecked<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateChecked<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateChecked<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateChecked<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateChecked<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateChecked<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateChecked<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateChecked<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateChecked<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateChecked<float>(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateChecked<ushort>(0x0000)); @@ -1662,6 +1835,26 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<NFloat>.CreateChecked<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1707,6 +1900,105 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateSaturating<decimal>(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateSaturating<decimal>(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(+1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateSaturating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateSaturating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateSaturating<double>(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateSaturating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateSaturating<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<double>(double.MaxValue)); + } + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper<NFloat>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateSaturating<Half>(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper<NFloat>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<NFloat>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + + [Fact] public static void CreateSaturatingFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateSaturating<short>(0x0000)); @@ -1755,6 +2047,25 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateSaturating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1776,6 +2087,34 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateSaturating<sbyte>(0x00)); @@ -1786,6 +2125,32 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateSaturating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateSaturating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateSaturating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateSaturating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateSaturating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateSaturating<ushort>(0x0000)); @@ -1836,6 +2201,26 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<NFloat>.CreateSaturating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1881,6 +2266,105 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual((NFloat)(+79228162514264337593543950335.0), NumberBaseHelper<NFloat>.CreateTruncating<decimal>(decimal.MaxValue)); + } + else + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<NFloat>.CreateTruncating<decimal>(decimal.MaxValue)); + } + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(-1.0)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(-0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(+0.0)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(1.0)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.MinValue)); + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateTruncating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateTruncating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateTruncating<double>(-double.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateTruncating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateTruncating<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.MaxValue)); + } + else + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.MinValue)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(-double.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<double>(2.2250738585072014E-308)); + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<double>(double.MaxValue)); + } + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.NegativeOne)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.Zero)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.NaN)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(-6.103515625E-05), NumberBaseHelper<NFloat>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual((NFloat)(-6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(-5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateTruncating<Half>(-Half.Epsilon)); + + AssertBitwiseEqual((NFloat)(+5.960464477539063E-08), NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual((NFloat)(+6.097555160522461E-05), NumberBaseHelper<NFloat>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual((NFloat)(+6.103515625E-05), NumberBaseHelper<NFloat>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + else + { + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(-Half.Epsilon)); + + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<NFloat>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + } + } + + [Fact] public static void CreateTruncatingFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateTruncating<short>(0x0000)); @@ -1929,6 +2413,25 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(+170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(-170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + else + { + AssertBitwiseEqual(+170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateTruncating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + } + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1950,6 +2453,34 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(1.0f)); + + AssertBitwiseEqual(NFloat.MinValue, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+NFloat.Epsilon, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(NFloat.MaxValue, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateTruncating<sbyte>(0x00)); @@ -1960,6 +2491,32 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(NFloat.NegativeInfinity, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<NFloat>.CreateTruncating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateTruncating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<NFloat>.CreateTruncating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<NFloat>.CreateTruncating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45f, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<NFloat>.CreateTruncating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38f, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.MaxValue)); + + AssertBitwiseEqual(NFloat.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(NFloat.NaN, NumberBaseHelper<NFloat>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<NFloat>.CreateTruncating<ushort>(0x0000)); @@ -2010,6 +2567,26 @@ namespace System.Runtime.InteropServices.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + AssertBitwiseEqual(0.0f, NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0f, NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105727.0), NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual((NFloat)(170141183460469231731687303715884105728.0), NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual((NFloat)(340282366920938463463374607431768211455.0), NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + else + { + AssertBitwiseEqual(170141183460469231731687303715884105727.0f, NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0f, NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<NFloat>.CreateTruncating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -2454,329 +3031,6 @@ namespace System.Runtime.InteropServices.Tests AssertBitwiseEqual(One, NumberBaseHelper<NFloat>.MinMagnitudeNumber(NFloat.PositiveInfinity, One)); } - [Fact] - public static void TryCreateFromByteTest() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<byte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<byte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((NFloat)127.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<byte>(0x80, out result)); - Assert.Equal((NFloat)128.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((NFloat)255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((NFloat)32768.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((NFloat)65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<short>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<short>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((NFloat)(-32768.0f), result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0), result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0f), result); - } - } - - [Fact] - public static void TryCreateFromInt64Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(NegativeOne, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal((NFloat)(-9223372036854775808.0), result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<long>(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<NFloat>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((NFloat)(-9223372036854775808.0), result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((NFloat)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((NFloat)127.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((NFloat)(-128.0f), result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((NFloat)32767.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((NFloat)32768.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((NFloat)65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(One, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((NFloat)2147483648.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((NFloat)4294967295.0, result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((NFloat)2147483648.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((NFloat)4294967295.0f, result); - } - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - NFloat result; - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((NFloat)9223372036854775808.0, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((NFloat)9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((NFloat)18446744073709551615.0f, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - NFloat result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((NFloat)9223372036854775807.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal((NFloat)9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal((NFloat)18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((NFloat)2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - // Assert.Equal((NFloat)2147483648.0f, result); - // - // Assert.True(NumberBaseHelper<NFloat>.TryCreate<nuint>(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 a7a99ca8c23..8c09f8a7db6 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Numerics.BigInteger CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Numerics.BigInteger CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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<System.Numerics.BigInteger>.IsZero(System.Numerics.BigInteger value) { throw null; } static System.Numerics.BigInteger System.Numerics.INumberBase<System.Numerics.BigInteger>.MaxMagnitudeNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static System.Numerics.BigInteger System.Numerics.INumberBase<System.Numerics.BigInteger>.MinMagnitudeNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertFromChecked<TOther>(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertFromSaturating<TOther>(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertFromTruncating<TOther>(TOther value, out System.Numerics.BigInteger result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertToChecked<TOther>(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertToSaturating<TOther>(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.BigInteger>.TryConvertToTruncating<TOther>(System.Numerics.BigInteger value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Numerics.BigInteger System.Numerics.INumber<System.Numerics.BigInteger>.MaxNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static System.Numerics.BigInteger System.Numerics.INumber<System.Numerics.BigInteger>.MinNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static int System.Numerics.INumber<System.Numerics.BigInteger>.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>(TOther value, out System.Numerics.BigInteger result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> value, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.BigInteger result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Numerics.Complex CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Numerics.Complex CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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<System.Numerics.Complex>.IsZero(System.Numerics.Complex value) { throw null; } static System.Numerics.Complex System.Numerics.INumberBase<System.Numerics.Complex>.MaxMagnitudeNumber(System.Numerics.Complex x, System.Numerics.Complex y) { throw null; } static System.Numerics.Complex System.Numerics.INumberBase<System.Numerics.Complex>.MinMagnitudeNumber(System.Numerics.Complex x, System.Numerics.Complex y) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertFromChecked<TOther>(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertFromSaturating<TOther>(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertFromTruncating<TOther>(TOther value, out System.Numerics.Complex result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertToChecked<TOther>(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertToSaturating<TOther>(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Numerics.Complex>.TryConvertToTruncating<TOther>(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Numerics.Complex System.Numerics.ISubtractionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>.operator checked -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } static System.Numerics.Complex System.Numerics.IUnaryNegationOperators<System.Numerics.Complex, System.Numerics.Complex>.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>(TOther value, out System.Numerics.Complex result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, System.ReadOnlySpan<char> format, System.IFormatProvider? provider) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.Complex result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> 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 e079da8ca7c..39c8346a54e 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 @@ namespace System.Numerics 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) + /// <summary>Explicitly converts a big integer to a <see cref="char" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="char" /> value.</returns> + 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) + /// <summary>Explicitly converts a big integer to a <see cref="Half" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="Half" /> value.</returns> + 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 @@ namespace System.Numerics 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 @@ namespace System.Numerics 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 @@ namespace System.Numerics 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]; - } - + /// <summary>Explicitly converts a big integer to a <see cref="Int128" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="Int128" /> value.</returns> public static explicit operator Int128(BigInteger value) { value.AssertValid(); @@ -2089,6 +1934,81 @@ namespace System.Numerics throw new OverflowException(SR.Overflow_Int128); } + /// <summary>Explicitly converts a big integer to a <see cref="IntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="IntPtr" /> value.</returns> + public static explicit operator nint(BigInteger value) + { + if (Environment.Is64BitProcess) + { + 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]; + } + + /// <summary>Explicitly converts a big integer to a <see cref="UInt128" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="UInt128" /> value.</returns> [CLSCompliant(false)] public static explicit operator UInt128(BigInteger value) { @@ -2120,92 +2040,252 @@ namespace System.Numerics return value._bits[0]; } - public static explicit operator nint(BigInteger value) + /// <summary>Explicitly converts a big integer to a <see cref="UIntPtr" /> value.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to <see cref="UIntPtr" /> value.</returns> + [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); + } + + /// <summary>Explicitly converts a <see cref="Half" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + public static explicit operator BigInteger(Half value) + { + return new BigInteger((float)value); + } + + /// <summary>Explicitly converts a <see cref="Complex" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + 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; + /// <summary>Implicitly converts a <see cref="char" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + 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) + /// <summary>Implicitly converts a <see cref="Int128" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + 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); + /// <summary>Implicitly converts a <see cref="IntPtr" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + 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; + /// <summary>Implicitly converts a <see cref="UInt128" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + [CLSCompliant(false)] + public static implicit operator BigInteger(UInt128 value) + { + int sign = +1; + uint[]? bits; - unchecked + if (value <= (uint)int.MaxValue) { - if (length > 2) hi = (int)value._bits[2]; - if (length > 1) mi = (int)value._bits[1]; - if (length > 0) lo = (int)value._bits[0]; + 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 decimal(lo, mi, hi, value._sign < 0, 0); + return new BigInteger(sign, bits); + } + + /// <summary>Implicitly converts a <see cref="UIntPtr" /> value to a big integer.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a big integer.</returns> + [CLSCompliant(false)] + public static implicit operator BigInteger(nuint value) + { + if (Environment.Is64BitProcess) + { + return new BigInteger(value); + } + else + { + return new BigInteger((uint)value); + } } public static BigInteger operator &(BigInteger left, BigInteger right) @@ -3888,453 +3968,1180 @@ namespace System.Numerics /// <inheritdoc cref="INumberBase{TSelf}.Radix" /> static int INumberBase<BigInteger>.Radix => 2; - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> + static bool INumberBase<BigInteger>.IsCanonical(BigInteger value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> + static bool INumberBase<BigInteger>.IsComplexNumber(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> + public static bool IsEvenInteger(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return (value._sign & 1) == 0; + } + return (value._bits[0] & 1) == 0; + } + + /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> + static bool INumberBase<BigInteger>.IsFinite(BigInteger value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> + static bool INumberBase<BigInteger>.IsImaginaryNumber(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> + static bool INumberBase<BigInteger>.IsInfinity(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> + static bool INumberBase<BigInteger>.IsInteger(BigInteger value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> + static bool INumberBase<BigInteger>.IsNaN(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> + public static bool IsNegative(BigInteger value) + { + value.AssertValid(); + return value._sign < 0; + } + + /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> + static bool INumberBase<BigInteger>.IsNegativeInfinity(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> + static bool INumberBase<BigInteger>.IsNormal(BigInteger value) => (value != 0); + + /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> + public static bool IsOddInteger(BigInteger value) + { + value.AssertValid(); + + if (value._bits is null) + { + return (value._sign & 1) != 0; + } + return (value._bits[0] & 1) != 0; + } + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> + public static bool IsPositive(BigInteger value) + { + value.AssertValid(); + return value._sign >= 0; + } + + /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> + static bool INumberBase<BigInteger>.IsPositiveInfinity(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> + static bool INumberBase<BigInteger>.IsRealNumber(BigInteger value) => true; + + /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> + static bool INumberBase<BigInteger>.IsSubnormal(BigInteger value) => false; + + /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> + static bool INumberBase<BigInteger>.IsZero(BigInteger value) + { + value.AssertValid(); + return value._sign == 0; + } + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> + 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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> + static BigInteger INumberBase<BigInteger>.MaxMagnitudeNumber(BigInteger x, BigInteger y) => MaxMagnitude(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> + 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; + } + + /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> + static BigInteger INumberBase<BigInteger>.MinMagnitudeNumber(BigInteger x, BigInteger y) => MinMagnitude(x, y); + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<BigInteger>.TryConvertFromChecked<TOther>(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 = 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)) { - 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 = checked((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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<BigInteger>.TryConvertFromSaturating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static BigInteger CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> + static bool INumberBase<BigInteger>.TryConvertFromTruncating<TOther>(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; } } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> - static bool INumberBase<BigInteger>.IsCanonical(BigInteger value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsComplexNumber(TSelf)" /> - static bool INumberBase<BigInteger>.IsComplexNumber(BigInteger value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsEvenInteger(TSelf)" /> - public static bool IsEvenInteger(BigInteger value) + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<BigInteger>.TryConvertToChecked<TOther>(BigInteger value, [NotNullWhen(true)] out TOther result) { - value.AssertValid(); - - if (value._bits is null) + if (typeof(TOther) == typeof(byte)) { - return (value._sign & 1) == 0; + 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 = (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 = 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(Complex)) + { + Complex actualResult = (Complex)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 = checked((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; } - return (value._bits[0] & 1) == 0; } - /// <inheritdoc cref="INumberBase{TSelf}.IsFinite(TSelf)" /> - static bool INumberBase<BigInteger>.IsFinite(BigInteger value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsImaginaryNumber(TSelf)" /> - static bool INumberBase<BigInteger>.IsImaginaryNumber(BigInteger value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInfinity(TSelf)" /> - static bool INumberBase<BigInteger>.IsInfinity(BigInteger value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsInteger(TSelf)" /> - static bool INumberBase<BigInteger>.IsInteger(BigInteger value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNaN(TSelf)" /> - static bool INumberBase<BigInteger>.IsNaN(BigInteger value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsNegative(TSelf)" /> - public static bool IsNegative(BigInteger value) + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<BigInteger>.TryConvertToSaturating<TOther>(BigInteger value, [NotNullWhen(true)] out TOther result) { - value.AssertValid(); - return value._sign < 0; - } + if (typeof(TOther) == typeof(byte)) + { + byte actualResult; - /// <inheritdoc cref="INumberBase{TSelf}.IsNegativeInfinity(TSelf)" /> - static bool INumberBase<BigInteger>.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; + } - /// <inheritdoc cref="INumberBase{TSelf}.IsNormal(TSelf)" /> - static bool INumberBase<BigInteger>.IsNormal(BigInteger value) => (value != 0); + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(char)) + { + char actualResult; - /// <inheritdoc cref="INumberBase{TSelf}.IsOddInteger(TSelf)" /> - 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; - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositive(TSelf)" /> - public static bool IsPositive(BigInteger value) - { - value.AssertValid(); - return value._sign >= 0; - } - - /// <inheritdoc cref="INumberBase{TSelf}.IsPositiveInfinity(TSelf)" /> - static bool INumberBase<BigInteger>.IsPositiveInfinity(BigInteger value) => false; - - /// <inheritdoc cref="INumberBase{TSelf}.IsRealNumber(TSelf)" /> - static bool INumberBase<BigInteger>.IsRealNumber(BigInteger value) => true; - - /// <inheritdoc cref="INumberBase{TSelf}.IsSubnormal(TSelf)" /> - static bool INumberBase<BigInteger>.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; - /// <inheritdoc cref="INumberBase{TSelf}.IsZero(TSelf)" /> - static bool INumberBase<BigInteger>.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; + } - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitude(TSelf, TSelf)" /> - 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)) { - return x; + long actualResult = (value >= long.MaxValue) ? long.MaxValue : + (value <= long.MinValue) ? long.MinValue : (long)value; + result = (TOther)(object)actualResult; + return true; } - - if (ax == ay) + else if (typeof(TOther) == typeof(Int128)) { - return IsNegative(x) ? y : x; + Int128 actualResult = (value >= Int128.MaxValue) ? Int128.MaxValue : + (value <= Int128.MinValue) ? 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(Complex)) + { + Complex actualResult = (Complex)value; + result = (TOther)(object)actualResult; + return true; + } + else if (typeof(TOther) == typeof(sbyte)) + { + sbyte actualResult; - return y; - } - - /// <inheritdoc cref="INumberBase{TSelf}.MaxMagnitudeNumber(TSelf, TSelf)" /> - static BigInteger INumberBase<BigInteger>.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; + } - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitude(TSelf, TSelf)" /> - 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; } - /// <inheritdoc cref="INumberBase{TSelf}.MinMagnitudeNumber(TSelf, TSelf)" /> - static BigInteger INumberBase<BigInteger>.MinMagnitudeNumber(BigInteger x, BigInteger y) => MinMagnitude(x, y); - - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out BigInteger result) - where TOther : INumberBase<TOther> + static bool INumberBase<BigInteger>.TryConvertToTruncating<TOther>(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 9d67f3058e5..534605a6ac2 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; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Numerics { @@ -799,35 +800,86 @@ namespace System.Numerics 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); + } + + /// <summary>Explicitly converts a <see cref="Int128" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + 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); + } + + /// <summary>Explicitly converts a <see cref="UInt128" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + [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) + /// <summary>Implicitly converts a <see cref="char" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + 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) + /// <summary>Implicitly converts a <see cref="Half" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + 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); + } + + /// <summary>Implicitly converts a <see cref="IntPtr" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + public static implicit operator Complex(nint value) { return new Complex(value, 0.0); } @@ -838,29 +890,36 @@ namespace System.Numerics 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) + /// <summary>Implicitly converts a <see cref="UIntPtr" /> value to a double-precision complex number.</summary> + /// <param name="value">The value to convert.</param> + /// <returns><paramref name="value" /> converted to a double-precision complex number.</returns> + [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 @@ namespace System.Numerics /// <inheritdoc cref="INumberBase{TSelf}.Abs(TSelf)" /> static Complex INumberBase<Complex>.Abs(Complex value) => Abs(value); - /// <inheritdoc cref="INumberBase{TSelf}.CreateChecked{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateChecked<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateSaturating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - - /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Complex CreateTruncating<TOther>(TOther value) - where TOther : INumberBase<TOther> - { - 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; - } - } - /// <inheritdoc cref="INumberBase{TSelf}.IsCanonical(TSelf)" /> static bool INumberBase<Complex>.IsCanonical(Complex value) => true; @@ -1598,89 +1453,621 @@ namespace System.Numerics return Parse(s.AsSpan(), style, provider); } - /// <inheritdoc cref="INumberBase{TSelf}.TryCreate{TOther}(TOther, out TSelf)" /> + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Complex>.TryConvertFromChecked<TOther>(TOther value, out Complex result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromSaturating{TOther}(TOther, out TSelf)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Complex>.TryConvertFromSaturating<TOther>(TOther value, out Complex result) + { + return TryConvertFrom<TOther>(value, out result); + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryCreate<TOther>(TOther value, out Complex result) + static bool INumberBase<Complex>.TryConvertFromTruncating<TOther>(TOther value, out Complex result) + { + return TryConvertFrom<TOther>(value, out result); + } + + private static bool TryConvertFrom<TOther>(TOther value, out Complex result) where TOther : INumberBase<TOther> { + // 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; } } + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToChecked{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Complex>.TryConvertToChecked<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Complex>.TryConvertToSaturating<TOther>(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; + } + } + + /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool INumberBase<Complex>.TryConvertToTruncating<TOther>(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; + } + } + /// <inheritdoc cref="INumberBase{TSelf}.TryParse(ReadOnlySpan{char}, NumberStyles, IFormatProvider?, out TSelf)" /> public static bool TryParse(ReadOnlySpan<char> 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 889aa29edc3..784c75ab9be 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 @@ -1041,6 +1042,60 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<decimal>(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateChecked<decimal>(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateChecked<decimal>(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper<BigInteger>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper<BigInteger>.CreateChecked<decimal>(decimal.MinValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<double>(+0.0)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<double>(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateChecked<double>(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateChecked<double>(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateChecked<double>(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateChecked<double>(-170141183460469212842221372237303250944.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<Half>((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<Half>((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateChecked<Half>((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateChecked<Half>((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper<BigInteger>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper<BigInteger>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<short>(0x0000)); @@ -1071,6 +1126,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1102,6 +1167,27 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<float>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<float>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateChecked<float>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateChecked<float>(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateChecked<float>(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateChecked<float>(-170141173319264429905852091742258462720.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<ushort>(0x0000)); @@ -1132,6 +1218,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateChecked<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<BigInteger>.CreateChecked<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<BigInteger>.CreateChecked<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper<BigInteger>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1173,6 +1269,60 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<decimal>(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateSaturating<decimal>(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateSaturating<decimal>(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper<BigInteger>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper<BigInteger>.CreateSaturating<decimal>(decimal.MinValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<double>(+0.0)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<double>(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateSaturating<double>(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateSaturating<double>(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateSaturating<double>(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateSaturating<double>(-170141183460469212842221372237303250944.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<Half>((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<Half>((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateSaturating<Half>((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateSaturating<Half>((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper<BigInteger>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper<BigInteger>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<short>(0x0000)); @@ -1203,6 +1353,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1234,6 +1394,27 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<float>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<float>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateSaturating<float>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateSaturating<float>(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateSaturating<float>(-170141173319264429905852091742258462720.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<ushort>(0x0000)); @@ -1264,6 +1445,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<BigInteger>.CreateSaturating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<BigInteger>.CreateSaturating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper<BigInteger>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1305,6 +1496,60 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<decimal>(decimal.Zero)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateTruncating<decimal>(decimal.One)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateTruncating<decimal>(decimal.MinusOne)); + + Assert.Equal((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper<BigInteger>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)), NumberBaseHelper<BigInteger>.CreateTruncating<decimal>(decimal.MinValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<double>(+0.0)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<double>(-0.0)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateTruncating<double>(+1.0)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateTruncating<double>(-1.0)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateTruncating<double>(+170141183460469212842221372237303250944.0)); + Assert.Equal((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateTruncating<double>(-170141183460469212842221372237303250944.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<Half>((Half)(+0.0))); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<Half>((Half)(-0.0))); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateTruncating<Half>((Half)(+1.0))); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateTruncating<Half>((Half)(-1.0))); + + Assert.Equal(+65504, NumberBaseHelper<BigInteger>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(-65504, NumberBaseHelper<BigInteger>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<short>(0x0000)); @@ -1335,6 +1580,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1366,6 +1621,27 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<float>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<float>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateTruncating<float>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<BigInteger>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateTruncating<float>(+170141173319264429905852091742258462720.0f)); + Assert.Equal((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)), NumberBaseHelper<BigInteger>.CreateTruncating<float>(-170141173319264429905852091742258462720.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<BigInteger>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<ushort>(0x0000)); @@ -1396,6 +1672,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<BigInteger>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<BigInteger>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<BigInteger>.CreateTruncating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<BigInteger>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(UInt128MaxValue, NumberBaseHelper<BigInteger>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1710,274 +1996,607 @@ namespace System.Numerics.Tests Assert.Equal(One, NumberBaseHelper<BigInteger>.MinMagnitudeNumber(UInt64MaxValue, 1)); } + // + // INumberBase.TryConvertTo + // + [Fact] - public static void TryCreateFromByteTest() + public static void TryConvertToCheckedByteTest() { - BigInteger result; - - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<byte>(0x00, out result)); - Assert.Equal(Zero, result); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<BigInteger>(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateChecked<BigInteger>(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateChecked<BigInteger>(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<BigInteger>(ByteMaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<byte>(0x01, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToCheckedCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<BigInteger>(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateChecked<BigInteger>(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateChecked<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateChecked<BigInteger>(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); + [Fact] + public static void TryConvertToCheckedDecimalTest() + { + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateChecked<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<byte>(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); + Assert.Equal(decimal.One, NumberBaseHelper<decimal>.CreateChecked<BigInteger>(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper<decimal>.CreateChecked<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateChecked<BigInteger>((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateChecked<BigInteger>((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<double>.CreateChecked<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0, NumberBaseHelper<double>.CreateChecked<BigInteger>(One)); + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateChecked<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(One, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateChecked<BigInteger>((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateChecked<BigInteger>((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToCheckedHalfTest() + { + Assert.Equal((Half)(+0.0), NumberBaseHelper<Half>.CreateChecked<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper<Half>.CreateChecked<BigInteger>(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper<Half>.CreateChecked<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateChecked<BigInteger>(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateChecked<BigInteger>(-65504)); } [Fact] - public static void TryCreateFromInt16Test() + public static void TryConvertToCheckedInt16Test() { - BigInteger result; + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateChecked<BigInteger>(One)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateChecked<BigInteger>(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<BigInteger>(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<short>(0x0000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToCheckedInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper<int>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper<int>.CreateChecked<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper<int>.CreateChecked<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateChecked<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<short>(0x0001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToCheckedInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateChecked<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked(unchecked((long)0x8000_0000_0000_0000)), NumberBaseHelper<long>.CreateChecked<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked(unchecked((long)0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper<long>.CreateChecked<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToCheckedInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<short>(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<nint>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper<nint>.CreateChecked<BigInteger>(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateChecked<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<BigInteger>(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<BigInteger>(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateChecked<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateChecked<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<BigInteger>(NegativeOne)); + } + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToCheckedSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateChecked<BigInteger>(One)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateChecked<BigInteger>(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<BigInteger>(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<BigInteger>(NegativeOne)); } [Fact] - public static void TryCreateFromInt32Test() + public static void TryConvertToCheckedSingleTest() { - BigInteger result; + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateChecked<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0f, NumberBaseHelper<float>.CreateChecked<BigInteger>(One)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateChecked<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateChecked<BigInteger>((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateChecked<BigInteger>((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToCheckedUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<BigInteger>(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateChecked<BigInteger>(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateChecked<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateChecked<BigInteger>(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); + [Fact] + public static void TryConvertToCheckedUInt32Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<BigInteger>(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper<uint>.CreateChecked<BigInteger>(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper<uint>.CreateChecked<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateChecked<BigInteger>(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToCheckedUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<BigInteger>(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateChecked<BigInteger>(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateChecked<BigInteger>(UInt64MaxValue)); } [Fact] - public static void TryCreateFromInt64Test() + public static void TryConvertToCheckedUInt128Test() { - BigInteger result; + Assert.Equal(UInt128.Zero, NumberBaseHelper<UInt128>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper<UInt128>.CreateChecked<BigInteger>(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<UInt128>.CreateChecked<BigInteger>(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<BigInteger>(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper<UInt128>.CreateChecked<BigInteger>(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<long>(0x00000000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToCheckedUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Zero)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateChecked<BigInteger>(One)); + Assert.Equal(unchecked((nuint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nuint>.CreateChecked<BigInteger>(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<BigInteger>(One)); + Assert.Equal((nuint)0x7FFF_FFFF, NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Int32MaxValue)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper<nuint>.CreateChecked<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateChecked<BigInteger>(UInt32MaxValue)); + } + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<long>(0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<BigInteger>(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateSaturating<BigInteger>(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateSaturating<BigInteger>(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<BigInteger>(ByteMaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToSaturatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<BigInteger>(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateSaturating<BigInteger>(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateSaturating<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<BigInteger>(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); + [Fact] + public static void TryConvertToSaturatingDecimalTest() + { + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateSaturating<BigInteger>(Zero)); + + Assert.Equal(decimal.One, NumberBaseHelper<decimal>.CreateSaturating<BigInteger>(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper<decimal>.CreateSaturating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<BigInteger>((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<BigInteger>((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<double>.CreateSaturating<BigInteger>(Zero)); - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0x00000000), out result)); - Assert.Equal(Zero, result); + Assert.Equal(+1.0, NumberBaseHelper<double>.CreateSaturating<BigInteger>(One)); + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateSaturating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0x00000001), out result)); - Assert.Equal(One, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateSaturating<BigInteger>((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateSaturating<BigInteger>((BigInteger)(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToSaturatingHalfTest() + { + Assert.Equal((Half)(+0.0), NumberBaseHelper<Half>.CreateSaturating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper<Half>.CreateSaturating<BigInteger>(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper<Half>.CreateSaturating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateSaturating<BigInteger>(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateSaturating<BigInteger>(-65504)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateSaturating<BigInteger>(One)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateSaturating<BigInteger>(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<BigInteger>(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<BigInteger>(NegativeOne)); + } + + [Fact] + public static void TryConvertToSaturatingInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper<int>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper<int>.CreateSaturating<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToSaturatingInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateSaturating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); + [Fact] + public static void TryConvertToSaturatingInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nint>(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<nint>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<BigInteger>(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateSaturating<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<BigInteger>(NegativeOne)); } } [Fact] - public static void TryCreateFromSByteTest() + public static void TryConvertToSaturatingSByteTest() { - BigInteger result; - - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(Zero, result); + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateSaturating<BigInteger>(One)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateSaturating<BigInteger>(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<BigInteger>(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingSingleTest() + { + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateSaturating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); + Assert.Equal(+1.0f, NumberBaseHelper<float>.CreateSaturating<BigInteger>(One)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateSaturating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(SByteMinValue, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateSaturating<BigInteger>((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateSaturating<BigInteger>((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); + [Fact] + public static void TryConvertToSaturatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<BigInteger>(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateSaturating<BigInteger>(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateSaturating<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<BigInteger>(UInt16MaxValue)); } [Fact] - public static void TryCreateFromUInt16Test() + public static void TryConvertToSaturatingUInt32Test() { - BigInteger result; + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<BigInteger>(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<BigInteger>(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper<uint>.CreateSaturating<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<BigInteger>(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToSaturatingUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<BigInteger>(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<BigInteger>(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<BigInteger>(UInt64MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToSaturatingUInt128Test() + { + Assert.Equal(UInt128.Zero, NumberBaseHelper<UInt128>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper<UInt128>.CreateSaturating<BigInteger>(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<UInt128>.CreateSaturating<BigInteger>(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<BigInteger>(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<BigInteger>(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); + [Fact] + public static void TryConvertToSaturatingUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0000), NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(One)); + Assert.Equal(unchecked((nuint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(One)); + Assert.Equal((nuint)0x7FFF_FFFF, NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Int32MaxValue)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateSaturating<BigInteger>(UInt32MaxValue)); + } + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<BigInteger>(One)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateTruncating<BigInteger>(SByteMaxValue)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateTruncating<BigInteger>(SByteMaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<BigInteger>(ByteMaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); + [Fact] + public static void TryConvertToTruncatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<BigInteger>(One)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateTruncating<BigInteger>(Int16MaxValue)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateTruncating<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<BigInteger>(UInt16MaxValue)); } [Fact] - public static void TryCreateFromUInt32Test() + public static void TryConvertToTruncatingDecimalTest() { - BigInteger result; + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateTruncating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal(decimal.One, NumberBaseHelper<decimal>.CreateTruncating<BigInteger>(One)); + Assert.Equal(decimal.MinusOne, NumberBaseHelper<decimal>.CreateTruncating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<BigInteger>((BigInteger)(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF)))); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<BigInteger>((BigInteger)(new Int128(0xFFFF_FFFF_0000_0000, 0x0000_0000_0000_0001)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingDoubleTest() + { + Assert.Equal(+0.0, NumberBaseHelper<double>.CreateTruncating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); + Assert.Equal(+1.0, NumberBaseHelper<double>.CreateTruncating<BigInteger>(One)); + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateTruncating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); + Assert.Equal(+170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateTruncating<BigInteger>((BigInteger)(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141183460469212842221372237303250944.0, NumberBaseHelper<double>.CreateTruncating<BigInteger>((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<Half>.CreateTruncating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ulong>(0x00000000, out result)); - Assert.Equal(Zero, result); + Assert.Equal((Half)(+1.0), NumberBaseHelper<Half>.CreateTruncating<BigInteger>(One)); + Assert.Equal((Half)(-1.0), NumberBaseHelper<Half>.CreateTruncating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ulong>(0x00000001, out result)); - Assert.Equal(One, result); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateTruncating<BigInteger>(+65504)); + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateTruncating<BigInteger>(-65504)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); + [Fact] + public static void TryConvertToTruncatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateTruncating<BigInteger>(One)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateTruncating<BigInteger>(Int16MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<BigInteger>(Int16MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingInt32Test() + { + Assert.Equal(0x0000_0000, NumberBaseHelper<int>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(0x0000_0001, NumberBaseHelper<int>.CreateTruncating<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF, NumberBaseHelper<int>.CreateTruncating<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); + [Fact] + public static void TryConvertToTruncatingInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<BigInteger>(One)); + Assert.Equal(0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateTruncating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<BigInteger>(NegativeOne)); } [Fact] - public static void TryCreateFromUIntPtrTest() + public static void TryConvertToTruncatingInt128Test() { - BigInteger result; + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MinValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + [Fact] + public static void TryConvertToTruncatingIntPtrTest() + { if (Environment.Is64BitProcess) { - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0x00000000), out result)); - Assert.Equal(Zero, result); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(unchecked((nint)0x0000_0001), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(One)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Int64MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(NegativeOne)); + } + else + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<BigInteger>(One)); + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Int32MaxValue)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(Int32MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<BigInteger>(NegativeOne)); + } + } + + [Fact] + public static void TryConvertToTruncatingSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateTruncating<BigInteger>(One)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateTruncating<BigInteger>(SByteMaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<BigInteger>(SByteMinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<BigInteger>(NegativeOne)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0x00000001), out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToTruncatingSingleTest() + { + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateTruncating<BigInteger>(Zero)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); + Assert.Equal(+1.0f, NumberBaseHelper<float>.CreateTruncating<BigInteger>(One)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateTruncating<BigInteger>(NegativeOne)); - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); + Assert.Equal(+170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateTruncating<BigInteger>((BigInteger)(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000)))); + Assert.Equal(-170141173319264429905852091742258462720.0f, NumberBaseHelper<float>.CreateTruncating<BigInteger>((BigInteger)(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000)))); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); + [Fact] + public static void TryConvertToTruncatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<BigInteger>(One)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateTruncating<BigInteger>(Int16MaxValue)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateTruncating<BigInteger>(Int16MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<BigInteger>(UInt16MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(One, result); + [Fact] + public static void TryConvertToTruncatingUInt32Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<BigInteger>(One)); + Assert.Equal((uint)0x7FFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<BigInteger>(Int32MaxValue)); + Assert.Equal((uint)0x8000_0000, NumberBaseHelper<uint>.CreateTruncating<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<BigInteger>(UInt32MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<BigInteger>(One)); + Assert.Equal((ulong)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<BigInteger>(Int64MaxValue)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<BigInteger>(UInt64MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); + [Fact] + public static void TryConvertToTruncatingUInt128Test() + { + Assert.Equal(UInt128.Zero, NumberBaseHelper<UInt128>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(UInt128.One, NumberBaseHelper<UInt128>.CreateTruncating<BigInteger>(One)); + Assert.Equal(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<UInt128>.CreateTruncating<BigInteger>(Int128MaxValue)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<BigInteger>(Int128MaxValuePlusOne)); + Assert.Equal(UInt128.MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<BigInteger>(UInt128MaxValue)); + } - Assert.True(NumberBaseHelper<BigInteger>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal(UInt32MaxValue, result); + [Fact] + public static void TryConvertToTruncatingUIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x00000000), NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal(unchecked((nuint)0x00000001), NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(One)); + Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Int64MaxValue)); + Assert.Equal(unchecked((nuint)0x8000000000000000), NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Int64MaxValuePlusOne)); + Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(UInt64MaxValue)); + } + else + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(One)); + Assert.Equal((nuint)0x7FFFFFFF, NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Int32MaxValue)); + Assert.Equal((nuint)0x80000000, NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(Int32MaxValuePlusOne)); + Assert.Equal((nuint)0xFFFFFFFF, NumberBaseHelper<nuint>.CreateTruncating<BigInteger>(UInt32MaxValue)); } } diff --git a/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs b/src/libraries/System.Runtime.Numerics/tests/ComplexTests.GenericMath.cs index 4425b15a9f0..06ceb1fc7a5 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 @@ -310,6 +311,69 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<Complex>.CreateChecked<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<Complex>.CreateChecked<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateChecked<double>(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateChecked<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateChecked<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<Complex>.CreateChecked<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateChecked<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateChecked<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<Complex>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateChecked<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateChecked<double>(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateChecked<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<Complex>.CreateChecked<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<Complex>.CreateChecked<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<Complex>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<Complex>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<Complex>.CreateChecked<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<Complex>.CreateChecked<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<Complex>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<Complex>.CreateChecked<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Complex>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateChecked<short>(0x0000)); @@ -340,6 +404,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateChecked<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateChecked<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateChecked<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateChecked<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateChecked<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -371,6 +445,32 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<Complex>.CreateChecked<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateChecked<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateChecked<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateChecked<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateChecked<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<Complex>.CreateChecked<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateChecked<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateChecked<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<Complex>.CreateChecked<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateChecked<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateChecked<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateChecked<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateChecked<float>(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<Complex>.CreateChecked<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<Complex>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateChecked<ushort>(0x0000)); @@ -401,6 +501,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateChecked<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateChecked<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateChecked<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateChecked<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper<Complex>.CreateChecked<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -446,6 +556,69 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<Complex>.CreateSaturating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<Complex>.CreateSaturating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateSaturating<double>(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateSaturating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateSaturating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<Complex>.CreateSaturating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateSaturating<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateSaturating<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<Complex>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateSaturating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateSaturating<double>(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateSaturating<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<Complex>.CreateSaturating<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<Complex>.CreateSaturating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<Complex>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<Complex>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<Complex>.CreateSaturating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<Complex>.CreateSaturating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<Complex>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<Complex>.CreateSaturating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Complex>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateSaturating<short>(0x0000)); @@ -476,6 +649,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateSaturating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateSaturating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateSaturating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateSaturating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateSaturating<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -507,6 +690,32 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<Complex>.CreateSaturating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateSaturating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateSaturating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateSaturating<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateSaturating<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<Complex>.CreateSaturating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateSaturating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateSaturating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<Complex>.CreateSaturating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateSaturating<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateSaturating<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateSaturating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateSaturating<float>(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<Complex>.CreateSaturating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<Complex>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateSaturating<ushort>(0x0000)); @@ -537,6 +746,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateSaturating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateSaturating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateSaturating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateSaturating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper<Complex>.CreateSaturating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -582,6 +801,69 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<Complex>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<Complex>.CreateTruncating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<Complex>.CreateTruncating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateTruncating<double>(-1.0)); + + AssertBitwiseEqual(-2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateTruncating<double>(-2.2250738585072014E-308)); + AssertBitwiseEqual(-2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateTruncating<double>(-2.2250738585072009E-308)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<Complex>.CreateTruncating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateTruncating<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateTruncating<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<Complex>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(+2.2250738585072009E-308, NumberBaseHelper<Complex>.CreateTruncating<double>(2.2250738585072009E-308)); + AssertBitwiseEqual(+2.2250738585072014E-308, NumberBaseHelper<Complex>.CreateTruncating<double>(2.2250738585072014E-308)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateTruncating<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<Complex>.CreateTruncating<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<Complex>.CreateTruncating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<Complex>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<Complex>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x0400))); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<Complex>.CreateTruncating<Half>(-BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<Complex>.CreateTruncating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<Complex>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x03FF))); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<Complex>.CreateTruncating<Half>(BitConverter.UInt16BitsToHalf(0x0400))); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Complex>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateTruncating<short>(0x0000)); @@ -612,6 +894,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateTruncating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateTruncating<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateTruncating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(-170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateTruncating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateTruncating<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -643,6 +935,32 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<Complex>.CreateTruncating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateTruncating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<Complex>.CreateTruncating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateTruncating<float>(-1.17549435E-38f)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateTruncating<float>(-1.17549421E-38f)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<Complex>.CreateTruncating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<Complex>.CreateTruncating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<Complex>.CreateTruncating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<Complex>.CreateTruncating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<Complex>.CreateTruncating<float>(1.17549421E-38f)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<Complex>.CreateTruncating<float>(1.17549435E-38f)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<Complex>.CreateTruncating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<Complex>.CreateTruncating<float>(float.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<Complex>.CreateTruncating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<Complex>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateTruncating<ushort>(0x0000)); @@ -673,6 +991,16 @@ namespace System.Numerics.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + AssertBitwiseEqual(0.0, NumberBaseHelper<Complex>.CreateTruncating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(1.0, NumberBaseHelper<Complex>.CreateTruncating<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001))); + AssertBitwiseEqual(170141183460469231731687303715884105727.0, NumberBaseHelper<Complex>.CreateTruncating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + AssertBitwiseEqual(170141183460469231731687303715884105728.0, NumberBaseHelper<Complex>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + AssertBitwiseEqual(340282366920938463463374607431768211455.0, NumberBaseHelper<Complex>.CreateTruncating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1877,277 +2205,700 @@ namespace System.Numerics.Tests AssertBitwiseEqual(new Complex(+1.0, +1.0), NumberBaseHelper<Complex>.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<byte>.CreateChecked<Complex>(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<Complex>(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateChecked<Complex>(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateChecked<Complex>(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<Complex>(255.0)); + } + + [Fact] + public static void TryConvertToCheckedCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Complex>(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<Complex>(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateChecked<Complex>(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateChecked<Complex>(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateChecked<Complex>(65535.0)); + } + + [Fact] + public static void TryConvertToCheckedDecimalTest() + { + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(-79228162514264333195497439231.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(+1.0)); + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<Complex>(+79228162514264333195497439231.0)); + } + [Fact] - public static void TryCreateFromByteTest() + public static void TryConvertToCheckedDoubleTest() { - Complex result; + Assert.Equal(double.NegativeInfinity, NumberBaseHelper<double>.CreateChecked<Complex>(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper<double>.CreateChecked<Complex>(double.MinValue)); + + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateChecked<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<byte>(0x00, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper<double>.CreateChecked<Complex>(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper<double>.CreateChecked<Complex>(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper<double>.CreateChecked<Complex>(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper<double>.CreateChecked<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<byte>(0x01, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0, NumberBaseHelper<double>.CreateChecked<Complex>(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper<double>.CreateChecked<Complex>(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper<double>.CreateChecked<Complex>(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper<double>.CreateChecked<Complex>(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(127.0, result); + Assert.Equal(1.0, NumberBaseHelper<double>.CreateChecked<Complex>(+1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<byte>(0x80, out result)); - Assert.Equal(128.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper<double>.CreateChecked<Complex>(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper<double>.CreateChecked<Complex>(double.PositiveInfinity)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(255.0, result); + Assert.Equal(double.NaN, NumberBaseHelper<double>.CreateChecked<Complex>(double.NaN)); } [Fact] - public static void TryCreateFromCharTest() + public static void TryConvertToCheckedHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<Complex>(Half.NegativeInfinity)); + + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateChecked<Complex>(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<Complex>(-1.0)); + + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateChecked<Complex>(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateChecked<Complex>(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper<Half>.CreateChecked<Complex>(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper<Half>.CreateChecked<Complex>(-0.0)); + + Assert.Equal(Half.Zero, NumberBaseHelper<Half>.CreateChecked<Complex>(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper<Half>.CreateChecked<Complex>(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateChecked<Complex>(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateChecked<Complex>(+6.103515625E-05)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.One, NumberBaseHelper<Half>.CreateChecked<Complex>(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateChecked<Complex>(+65504.0)); + + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<Complex>(Half.PositiveInfinity)); + + Assert.Equal(Half.NaN, NumberBaseHelper<Half>.CreateChecked<Complex>(Half.NaN)); + } + + [Fact] + public static void TryConvertToCheckedInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateChecked<Complex>(0.0)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateChecked<Complex>(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateChecked<Complex>(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<Complex>(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<Complex>(-1.0)); + } + + [Fact] + public static void TryConvertToCheckedInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper<int>.CreateChecked<Complex>(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper<int>.CreateChecked<Complex>(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper<int>.CreateChecked<Complex>(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper<int>.CreateChecked<Complex>(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper<int>.CreateChecked<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToCheckedInt64Test() + { + Assert.Equal(0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Complex>(0.0)); + Assert.Equal(0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<Complex>(1.0)); + Assert.Equal(0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateChecked<Complex>(+9223372036854774784.0)); + Assert.Equal(unchecked(unchecked((long)0x8000_0000_0000_0000)), NumberBaseHelper<long>.CreateChecked<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFF_FFFF_FFFF_FFFF)), NumberBaseHelper<long>.CreateChecked<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<char>((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<Int128>.CreateChecked<Complex>(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<Int128>.CreateChecked<Complex>(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<Complex>(+170141183460469212842221372237303250944.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<Complex>(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<Int128>.CreateChecked<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<char>((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<nint>.CreateChecked<Complex>(0.0)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0001), NumberBaseHelper<nint>.CreateChecked<Complex>(1.0)); + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateChecked<Complex>(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateChecked<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<Complex>(-1.0)); + } + else + { + Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateChecked<Complex>(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateChecked<Complex>(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper<nint>.CreateChecked<Complex>(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper<nint>.CreateChecked<Complex>(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper<nint>.CreateChecked<Complex>(-1.0)); + } + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(65535.0, result); + [Fact] + public static void TryConvertToCheckedSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateChecked<Complex>(0.0)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateChecked<Complex>(1.0)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateChecked<Complex>(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<Complex>(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<Complex>(-1.0)); } [Fact] - public static void TryCreateFromInt16Test() + public static void TryConvertToCheckedSingleTest() { - Complex result; + Assert.Equal(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<Complex>(float.NegativeInfinity)); + + Assert.Equal(float.MinValue, NumberBaseHelper<float>.CreateChecked<Complex>(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateChecked<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<short>(0x0000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.17549435E-38f, NumberBaseHelper<float>.CreateChecked<Complex>(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper<float>.CreateChecked<Complex>(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper<float>.CreateChecked<Complex>(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper<float>.CreateChecked<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<short>(0x0001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateChecked<Complex>(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper<float>.CreateChecked<Complex>(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper<float>.CreateChecked<Complex>(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper<float>.CreateChecked<Complex>(+1.1754943508222875E-38)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(32767.0, result); + Assert.Equal(1.0f, NumberBaseHelper<float>.CreateChecked<Complex>(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper<float>.CreateChecked<Complex>(+3.4028234663852886E+38)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0, result); + Assert.Equal(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<Complex>(float.PositiveInfinity)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(float.NaN, NumberBaseHelper<float>.CreateChecked<Complex>(float.NaN)); } [Fact] - public static void TryCreateFromInt32Test() + public static void TryConvertToCheckedUInt16Test() { - Complex result; + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Complex>(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<Complex>(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateChecked<Complex>(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateChecked<Complex>(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateChecked<Complex>(65535.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToCheckedUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<Complex>(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.CreateChecked<Complex>(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper<uint>.CreateChecked<Complex>(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper<uint>.CreateChecked<Complex>(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper<uint>.CreateChecked<Complex>(4294967295.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToCheckedUInt64Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Complex>(0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<Complex>(1.0)); + Assert.Equal((ulong)0x8000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Complex>(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateChecked<Complex>(18446744073709549568.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<int>(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<UInt128>.CreateChecked<Complex>(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<UInt128>.CreateChecked<Complex>(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<Complex>(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<Complex>(340282366920938425684442744474606501888.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<int>(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<nuint>.CreateChecked<Complex>(0.0)); + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateChecked<Complex>(1.0)); + Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper<nuint>.CreateChecked<Complex>(9223372036854775808.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateChecked<Complex>(18446744073709549568.0)); + } + else + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<Complex>(0.0)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<Complex>(1.0)); + Assert.Equal((nuint)0x8000_0000, NumberBaseHelper<nuint>.CreateChecked<Complex>(2147483648.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateChecked<Complex>(4294967295.0)); + } + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); + [Fact] + public static void TryConvertToSaturatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Complex>(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<Complex>(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateSaturating<Complex>(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateSaturating<Complex>(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Complex>(255.0)); + } + + [Fact] + public static void TryConvertToSaturatingCharTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Complex>(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<Complex>(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateSaturating<Complex>(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateSaturating<Complex>(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<Complex>(65535.0)); + } + + [Fact] + public static void TryConvertToSaturatingDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<Complex>(-79228162514264337593543950335.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<Complex>(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateSaturating<Complex>(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateSaturating<Complex>(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<Complex>(+1.0)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<Complex>(+79228162514264337593543950335.0)); } [Fact] - public static void TryCreateFromInt64Test() + public static void TryConvertToSaturatingDoubleTest() { - Complex result; + Assert.Equal(double.NegativeInfinity, NumberBaseHelper<double>.CreateSaturating<Complex>(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper<double>.CreateSaturating<Complex>(double.MinValue)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateSaturating<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper<double>.CreateSaturating<Complex>(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper<double>.CreateSaturating<Complex>(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper<double>.CreateSaturating<Complex>(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper<double>.CreateSaturating<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(+0.0, NumberBaseHelper<double>.CreateSaturating<Complex>(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper<double>.CreateSaturating<Complex>(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper<double>.CreateSaturating<Complex>(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper<double>.CreateSaturating<Complex>(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0, result); + Assert.Equal(1.0, NumberBaseHelper<double>.CreateSaturating<Complex>(+1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper<double>.CreateSaturating<Complex>(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper<double>.CreateSaturating<Complex>(double.PositiveInfinity)); + + Assert.Equal(double.NaN, NumberBaseHelper<double>.CreateSaturating<Complex>(double.NaN)); } [Fact] - public static void TryCreateFromIntPtrTest() + public static void TryConvertToSaturatingHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<Complex>(Half.NegativeInfinity)); - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateSaturating<Complex>(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateSaturating<Complex>(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateSaturating<Complex>(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper<Half>.CreateSaturating<Complex>(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper<Half>.CreateSaturating<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(Half.Zero, NumberBaseHelper<Half>.CreateSaturating<Complex>(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper<Half>.CreateSaturating<Complex>(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateSaturating<Complex>(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateSaturating<Complex>(+6.103515625E-05)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0, result); + Assert.Equal(Half.One, NumberBaseHelper<Half>.CreateSaturating<Complex>(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateSaturating<Complex>(+65504.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - else - { - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<Complex>(Half.PositiveInfinity)); + + Assert.Equal(Half.NaN, NumberBaseHelper<Half>.CreateSaturating<Complex>(Half.NaN)); + } + + [Fact] + public static void TryConvertToSaturatingInt16Test() + { + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateSaturating<Complex>(0.0)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateSaturating<Complex>(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateSaturating<Complex>(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Complex>(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToSaturatingInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper<int>.CreateSaturating<Complex>(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper<int>.CreateSaturating<Complex>(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper<int>.CreateSaturating<Complex>(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper<int>.CreateSaturating<Complex>(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper<int>.CreateSaturating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + [Fact] + public static void TryConvertToSaturatingInt64Test() + { + Assert.Equal(0x0000000000000000, NumberBaseHelper<long>.CreateSaturating<Complex>(0.0)); + Assert.Equal(0x0000000000000001, NumberBaseHelper<long>.CreateSaturating<Complex>(1.0)); + Assert.Equal(0x7FFFFFFFFFFFFFFF, NumberBaseHelper<long>.CreateSaturating<Complex>(9223372036854775807.0)); + Assert.Equal(unchecked(unchecked((long)0x8000000000000000)), NumberBaseHelper<long>.CreateSaturating<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), NumberBaseHelper<long>.CreateSaturating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(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<Int128>.CreateSaturating<Complex>(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<Int128>.CreateSaturating<Complex>(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<Int128>.CreateSaturating<Complex>(170141183460469231731687303715884105727.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateSaturating<Complex>(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<Int128>.CreateSaturating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); + [Fact] + public static void TryConvertToSaturatingIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000000000000000), NumberBaseHelper<nint>.CreateSaturating<Complex>(0.0)); + Assert.Equal(unchecked((nint)0x0000000000000001), NumberBaseHelper<nint>.CreateSaturating<Complex>(1.0)); + Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper<nint>.CreateSaturating<Complex>(9223372036854775807.0)); + Assert.Equal(unchecked((nint)0x8000000000000000), NumberBaseHelper<nint>.CreateSaturating<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper<nint>.CreateSaturating<Complex>(-1.0)); + } + else + { + Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateSaturating<Complex>(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateSaturating<Complex>(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper<nint>.CreateSaturating<Complex>(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper<nint>.CreateSaturating<Complex>(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper<nint>.CreateSaturating<Complex>(-1.0)); } } [Fact] - public static void TryCreateFromSByteTest() + public static void TryConvertToSaturatingSByteTest() { - Complex result; + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateSaturating<Complex>(0.0)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateSaturating<Complex>(1.0)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateSaturating<Complex>(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Complex>(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<Complex>(-1.0)); + } + + [Fact] + public static void TryConvertToSaturatingSingleTest() + { + Assert.Equal(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<Complex>(float.NegativeInfinity)); + + Assert.Equal(float.MinValue, NumberBaseHelper<float>.CreateSaturating<Complex>(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateSaturating<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-1.17549435E-38f, NumberBaseHelper<float>.CreateSaturating<Complex>(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper<float>.CreateSaturating<Complex>(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper<float>.CreateSaturating<Complex>(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper<float>.CreateSaturating<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(1.0, result); + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateSaturating<Complex>(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper<float>.CreateSaturating<Complex>(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper<float>.CreateSaturating<Complex>(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper<float>.CreateSaturating<Complex>(+1.1754943508222875E-38)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(127.0, result); + Assert.Equal(1.0f, NumberBaseHelper<float>.CreateSaturating<Complex>(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper<float>.CreateSaturating<Complex>(+3.4028234663852886E+38)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0, result); + Assert.Equal(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<Complex>(float.PositiveInfinity)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0, result); + Assert.Equal(float.NaN, NumberBaseHelper<float>.CreateSaturating<Complex>(float.NaN)); } [Fact] - public static void TryCreateFromUInt16Test() + public static void TryConvertToSaturatingUInt16Test() { - Complex result; + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Complex>(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<Complex>(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateSaturating<Complex>(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateSaturating<Complex>(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<Complex>(65535.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToSaturatingUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateSaturating<Complex>(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.CreateSaturating<Complex>(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper<uint>.CreateSaturating<Complex>(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper<uint>.CreateSaturating<Complex>(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper<uint>.CreateSaturating<Complex>(4294967295.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToSaturatingUInt64Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateSaturating<Complex>(0.0)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper<ulong>.CreateSaturating<Complex>(1.0)); + Assert.Equal((ulong)0x8000000000000000, NumberBaseHelper<ulong>.CreateSaturating<Complex>(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper<ulong>.CreateSaturating<Complex>(18446744073709551615.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<ushort>(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<UInt128>.CreateSaturating<Complex>(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<UInt128>.CreateSaturating<Complex>(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<Complex>(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<UInt128>.CreateSaturating<Complex>(340282366920938463463374607431768211455.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<ushort>(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<nuint>.CreateSaturating<Complex>(0.0)); + // Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateSaturating<Complex>(1.0)); + // Assert.Equal(unchecked((nuint)0x8000_0000_0000_0000), NumberBaseHelper<nuint>.CreateSaturating<Complex>(9223372036854775808.0)); + // Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nuint>.CreateSaturating<Complex>(18446744073709551615.0)); + // } + // else + // { + // Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Complex>(0.0)); + // Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<Complex>(1.0)); + // Assert.Equal((nuint)0x8000_0000, NumberBaseHelper<nuint>.CreateSaturating<Complex>(2147483648.0)); + // Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateSaturating<Complex>(4294967295.0)); + // } + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(65535.0, result); + [Fact] + public static void TryConvertToTruncatingByteTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Complex>(0.0)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<Complex>(1.0)); + Assert.Equal((byte)0x7F, NumberBaseHelper<byte>.CreateTruncating<Complex>(127.0)); + Assert.Equal((byte)0x80, NumberBaseHelper<byte>.CreateTruncating<Complex>(128.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Complex>(255.0)); } [Fact] - public static void TryCreateFromUInt32Test() + public static void TryConvertToTruncatingCharTest() { - Complex result; + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Complex>(0.0)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<Complex>(1.0)); + Assert.Equal((char)0x7FFF, NumberBaseHelper<char>.CreateTruncating<Complex>(32767.0)); + Assert.Equal((char)0x8000, NumberBaseHelper<char>.CreateTruncating<Complex>(32768.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<Complex>(65535.0)); + } + + [Fact] + public static void TryConvertToTruncatingDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<Complex>(-79228162514264337593543950335.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<Complex>(-1.0)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateTruncating<Complex>(-0.0)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateTruncating<Complex>(+0.0)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<Complex>(+1.0)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<Complex>(+79228162514264337593543950335.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToTruncatingDoubleTest() + { + Assert.Equal(double.NegativeInfinity, NumberBaseHelper<double>.CreateTruncating<Complex>(double.NegativeInfinity)); + Assert.Equal(double.MinValue, NumberBaseHelper<double>.CreateTruncating<Complex>(double.MinValue)); + + Assert.Equal(-1.0, NumberBaseHelper<double>.CreateTruncating<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(-2.2250738585072014E-308, NumberBaseHelper<double>.CreateTruncating<Complex>(-2.2250738585072014E-308)); + Assert.Equal(-2.2250738585072009E-308, NumberBaseHelper<double>.CreateTruncating<Complex>(-2.2250738585072009E-308)); + Assert.Equal(-double.Epsilon, NumberBaseHelper<double>.CreateTruncating<Complex>(-double.Epsilon)); + Assert.Equal(-0.0, NumberBaseHelper<double>.CreateTruncating<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + Assert.Equal(+0.0, NumberBaseHelper<double>.CreateTruncating<Complex>(+0.0)); + Assert.Equal(double.Epsilon, NumberBaseHelper<double>.CreateTruncating<Complex>(+double.Epsilon)); + Assert.Equal(2.2250738585072009E-308, NumberBaseHelper<double>.CreateTruncating<Complex>(+2.2250738585072009E-308)); + Assert.Equal(2.2250738585072014E-308, NumberBaseHelper<double>.CreateTruncating<Complex>(+2.2250738585072014E-308)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(2147483648.0, result); + Assert.Equal(1.0, NumberBaseHelper<double>.CreateTruncating<Complex>(+1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0, result); + Assert.Equal(double.MaxValue, NumberBaseHelper<double>.CreateTruncating<Complex>(double.MaxValue)); + Assert.Equal(double.PositiveInfinity, NumberBaseHelper<double>.CreateTruncating<Complex>(double.PositiveInfinity)); + + Assert.Equal(double.NaN, NumberBaseHelper<double>.CreateTruncating<Complex>(double.NaN)); } [Fact] - public static void TryCreateFromUInt64Test() + public static void TryConvertToTruncatingHalfTest() { - Complex result; + Assert.Equal(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<Complex>(Half.NegativeInfinity)); + + Assert.Equal(Half.MinValue, NumberBaseHelper<Half>.CreateTruncating<Complex>(-65504.0)); + Assert.Equal(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<Complex>(-1.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateTruncating<Complex>(-6.103515625E-05)); + Assert.Equal(-BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateTruncating<Complex>(-6.097555160522461E-05)); + Assert.Equal(-Half.Epsilon, NumberBaseHelper<Half>.CreateTruncating<Complex>(-5.960464477539063E-08)); + Assert.Equal(Half.NegativeZero, NumberBaseHelper<Half>.CreateTruncating<Complex>(-0.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(1.0, result); + Assert.Equal(Half.Zero, NumberBaseHelper<Half>.CreateTruncating<Complex>(+0.0)); + Assert.Equal(Half.Epsilon, NumberBaseHelper<Half>.CreateTruncating<Complex>(+5.960464477539063E-08)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x03FF), NumberBaseHelper<Half>.CreateTruncating<Complex>(+6.097555160522461E-05)); + Assert.Equal(BitConverter.UInt16BitsToHalf(0x0400), NumberBaseHelper<Half>.CreateTruncating<Complex>(+6.103515625E-05)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); + Assert.Equal(Half.One, NumberBaseHelper<Half>.CreateTruncating<Complex>(+1.0)); + Assert.Equal(Half.MaxValue, NumberBaseHelper<Half>.CreateTruncating<Complex>(+65504.0)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0, result); + Assert.Equal(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<Complex>(Half.PositiveInfinity)); - Assert.True(NumberBaseHelper<Complex>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0, result); + Assert.Equal(Half.NaN, NumberBaseHelper<Half>.CreateTruncating<Complex>(Half.NaN)); } [Fact] - public static void TryCreateFromUIntPtrTest() + public static void TryConvertToTruncatingInt16Test() { - Complex result; + Assert.Equal(0x0000, NumberBaseHelper<short>.CreateTruncating<Complex>(0.0)); + Assert.Equal(0x0001, NumberBaseHelper<short>.CreateTruncating<Complex>(1.0)); + Assert.Equal(0x7FFF, NumberBaseHelper<short>.CreateTruncating<Complex>(32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<Complex>(-32768.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<Complex>(-1.0)); + } - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); + [Fact] + public static void TryConvertToTruncatingInt32Test() + { + Assert.Equal(0x00000000, NumberBaseHelper<int>.CreateTruncating<Complex>(0.0)); + Assert.Equal(0x00000001, NumberBaseHelper<int>.CreateTruncating<Complex>(1.0)); + Assert.Equal(0x7FFFFFFF, NumberBaseHelper<int>.CreateTruncating<Complex>(2147483647.0)); + Assert.Equal(unchecked((int)0x80000000), NumberBaseHelper<int>.CreateTruncating<Complex>(-2147483648.0)); + Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper<int>.CreateTruncating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToTruncatingInt64Test() + { + Assert.Equal(0x0000000000000000, NumberBaseHelper<long>.CreateTruncating<Complex>(0.0)); + Assert.Equal(0x0000000000000001, NumberBaseHelper<long>.CreateTruncating<Complex>(1.0)); + Assert.Equal(unchecked(unchecked((long)0x8000000000000000)), NumberBaseHelper<long>.CreateTruncating<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), NumberBaseHelper<long>.CreateTruncating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(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<Int128>.CreateTruncating<Complex>(0.0)); + Assert.Equal(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<Int128>.CreateTruncating<Complex>(1.0)); + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<Int128>.CreateTruncating<Complex>(170141183460469231731687303715884105727.0)); + Assert.Equal(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateTruncating<Complex>(-170141183460469231731687303715884105728.0)); + Assert.Equal(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<Int128>.CreateTruncating<Complex>(-1.0)); + } - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0, result); + [Fact] + public static void TryConvertToTruncatingIntPtrTest() + { + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0x0000000000000000), NumberBaseHelper<nint>.CreateTruncating<Complex>(0.0)); + Assert.Equal(unchecked((nint)0x0000000000000001), NumberBaseHelper<nint>.CreateTruncating<Complex>(1.0)); + Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), NumberBaseHelper<nint>.CreateTruncating<Complex>(9223372036854775807.0)); + Assert.Equal(unchecked((nint)0x8000000000000000), NumberBaseHelper<nint>.CreateTruncating<Complex>(-9223372036854775808.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), NumberBaseHelper<nint>.CreateTruncating<Complex>(-1.0)); } else { - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(0.0, result); + Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateTruncating<Complex>(0.0)); + Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateTruncating<Complex>(1.0)); + Assert.Equal((nint)0x7FFFFFFF, NumberBaseHelper<nint>.CreateTruncating<Complex>(2147483647.0)); + Assert.Equal(unchecked((nint)0x80000000), NumberBaseHelper<nint>.CreateTruncating<Complex>(-2147483648.0)); + Assert.Equal(unchecked((nint)0xFFFFFFFF), NumberBaseHelper<nint>.CreateTruncating<Complex>(-1.0)); + } + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(1.0, result); + [Fact] + public static void TryConvertToTruncatingSByteTest() + { + Assert.Equal(0x00, NumberBaseHelper<sbyte>.CreateTruncating<Complex>(0.0)); + Assert.Equal(0x01, NumberBaseHelper<sbyte>.CreateTruncating<Complex>(1.0)); + Assert.Equal(0x7F, NumberBaseHelper<sbyte>.CreateTruncating<Complex>(127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<Complex>(-128.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<Complex>(-1.0)); + } - Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); + [Fact] + public static void TryConvertToTruncatingSingleTest() + { + Assert.Equal(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<Complex>(float.NegativeInfinity)); - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0, result); - // - // Assert.True(NumberBaseHelper<Complex>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFF), out result)); - // Assert.Equal(4294967295.0, result); - } + Assert.Equal(float.MinValue, NumberBaseHelper<float>.CreateTruncating<Complex>(-3.4028234663852886E+38)); + Assert.Equal(-1.0f, NumberBaseHelper<float>.CreateTruncating<Complex>(-1.0)); + + Assert.Equal(-1.17549435E-38f, NumberBaseHelper<float>.CreateTruncating<Complex>(-1.1754943508222875E-38)); + Assert.Equal(-1.17549421E-38f, NumberBaseHelper<float>.CreateTruncating<Complex>(-1.1754942106924411E-38)); + Assert.Equal(-float.Epsilon, NumberBaseHelper<float>.CreateTruncating<Complex>(-1.401298464324817E-45)); + Assert.Equal(-0.0f, NumberBaseHelper<float>.CreateTruncating<Complex>(-0.0)); + + Assert.Equal(+0.0f, NumberBaseHelper<float>.CreateTruncating<Complex>(+0.0)); + Assert.Equal(float.Epsilon, NumberBaseHelper<float>.CreateTruncating<Complex>(+1.401298464324817E-45)); + Assert.Equal(1.17549421E-38f, NumberBaseHelper<float>.CreateTruncating<Complex>(+1.1754942106924411E-38)); + Assert.Equal(1.17549435E-38f, NumberBaseHelper<float>.CreateTruncating<Complex>(+1.1754943508222875E-38)); + + Assert.Equal(1.0f, NumberBaseHelper<float>.CreateTruncating<Complex>(+1.0)); + Assert.Equal(float.MaxValue, NumberBaseHelper<float>.CreateTruncating<Complex>(+3.4028234663852886E+38)); + + Assert.Equal(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<Complex>(float.PositiveInfinity)); + + Assert.Equal(float.NaN, NumberBaseHelper<float>.CreateTruncating<Complex>(float.NaN)); + } + + [Fact] + public static void TryConvertToTruncatingUInt16Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Complex>(0.0)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<Complex>(1.0)); + Assert.Equal((ushort)0x7FFF, NumberBaseHelper<ushort>.CreateTruncating<Complex>(32767.0)); + Assert.Equal((ushort)0x8000, NumberBaseHelper<ushort>.CreateTruncating<Complex>(32768.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<Complex>(65535.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt32Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateTruncating<Complex>(0.0)); + Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.CreateTruncating<Complex>(1.0)); + Assert.Equal((uint)0x7FFFFFFF, NumberBaseHelper<uint>.CreateTruncating<Complex>(2147483647.0)); + Assert.Equal((uint)0x80000000, NumberBaseHelper<uint>.CreateTruncating<Complex>(2147483648.0)); + Assert.Equal((uint)0xFFFFFFFF, NumberBaseHelper<uint>.CreateTruncating<Complex>(4294967295.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt64Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateTruncating<Complex>(0.0)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper<ulong>.CreateTruncating<Complex>(1.0)); + Assert.Equal((ulong)0x8000000000000000, NumberBaseHelper<ulong>.CreateTruncating<Complex>(9223372036854775808.0)); + Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, NumberBaseHelper<ulong>.CreateTruncating<Complex>(18446744073709551615.0)); + } + + [Fact] + public static void TryConvertToTruncatingUInt128Test() + { + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<Complex>(0.0)); + Assert.Equal(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), NumberBaseHelper<UInt128>.CreateTruncating<Complex>(1.0)); + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<Complex>(170141183460469231731687303715884105728.0)); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<UInt128>.CreateTruncating<Complex>(340282366920938463463374607431768211455.0)); } // diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 490adf5a785..3203e394487 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -728,9 +728,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static byte CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static byte CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static byte System.Numerics.INumberBase<byte>.MaxMagnitudeNumber(byte x, byte y) { throw null; } static byte System.Numerics.INumberBase<byte>.MinMagnitude(byte x, byte y) { throw null; } static byte System.Numerics.INumberBase<byte>.MinMagnitudeNumber(byte x, byte y) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertFromChecked<TOther>(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertFromSaturating<TOther>(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertFromTruncating<TOther>(TOther value, out byte result) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertToChecked<TOther>(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertToSaturating<TOther>(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<byte>.TryConvertToTruncating<TOther>(byte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static byte System.Numerics.INumber<byte>.CopySign(byte value, byte sign) { throw null; } static byte System.Numerics.INumber<byte>.MaxNumber(byte x, byte y) { throw null; } static byte System.Numerics.INumber<byte>.MinNumber(byte x, byte y) { throw null; } @@ -829,7 +832,6 @@ namespace System 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>(TOther value, out byte result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, out byte result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out byte result) { throw null; } @@ -966,9 +968,6 @@ namespace System static char System.Numerics.IMultiplyOperators<char, char, char>.operator checked *(char left, char right) { throw null; } static char System.Numerics.IMultiplyOperators<char, char, char>.operator *(char left, char right) { throw null; } static char System.Numerics.INumberBase<char>.Abs(char value) { throw null; } - static char System.Numerics.INumberBase<char>.CreateChecked<TOther>(TOther value) { throw null; } - static char System.Numerics.INumberBase<char>.CreateSaturating<TOther>(TOther value) { throw null; } - static char System.Numerics.INumberBase<char>.CreateTruncating<TOther>(TOther value) { throw null; } static bool System.Numerics.INumberBase<char>.IsCanonical(char value) { throw null; } static bool System.Numerics.INumberBase<char>.IsComplexNumber(char value) { throw null; } static bool System.Numerics.INumberBase<char>.IsEvenInteger(char value) { throw null; } @@ -992,7 +991,12 @@ namespace System static char System.Numerics.INumberBase<char>.MinMagnitudeNumber(char x, char y) { throw null; } static char System.Numerics.INumberBase<char>.Parse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } static char System.Numerics.INumberBase<char>.Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } - static bool System.Numerics.INumberBase<char>.TryCreate<TOther>(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertFromChecked<TOther>(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertFromSaturating<TOther>(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertFromTruncating<TOther>(TOther value, out char result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertToChecked<TOther>(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertToSaturating<TOther>(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<char>.TryConvertToTruncating<TOther>(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase<char>.TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out char result) { throw null; } static bool System.Numerics.INumberBase<char>.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<char>.Clamp(char value, char min, char max) { throw null; } @@ -1888,9 +1892,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static decimal CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static decimal CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<decimal>.IsZero(decimal value) { throw null; } static decimal System.Numerics.INumberBase<decimal>.MaxMagnitudeNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.INumberBase<decimal>.MinMagnitudeNumber(decimal x, decimal y) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertFromChecked<TOther>(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertFromSaturating<TOther>(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertFromTruncating<TOther>(TOther value, out decimal result) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertToChecked<TOther>(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertToSaturating<TOther>(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<decimal>.TryConvertToTruncating<TOther>(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static decimal System.Numerics.INumber<decimal>.MaxNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.INumber<decimal>.MinNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.ISubtractionOperators<decimal, decimal, decimal>.operator checked -(decimal left, decimal right) { throw null; } @@ -2038,7 +2045,6 @@ namespace System [System.CLSCompliantAttribute(false)] public static ulong ToUInt64(decimal d) { throw null; } public static decimal Truncate(decimal d) { throw null; } - public static bool TryCreate<TOther>(TOther value, out decimal result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryGetBits(decimal d, System.Span<int> destination, out int valuesWritten) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, out decimal result) { throw null; } @@ -2141,9 +2147,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static double CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static double CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<double>.IsComplexNumber(double value) { throw null; } static bool System.Numerics.INumberBase<double>.IsImaginaryNumber(double value) { throw null; } static bool System.Numerics.INumberBase<double>.IsZero(double value) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertFromChecked<TOther>(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertFromSaturating<TOther>(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertFromTruncating<TOther>(TOther value, out double result) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertToChecked<TOther>(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertToSaturating<TOther>(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<double>.TryConvertToTruncating<TOther>(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static double System.Numerics.ISubtractionOperators<double, double, double>.operator checked -(double left, double right) { throw null; } static double System.Numerics.ISubtractionOperators<double, double, double>.operator -(double left, double right) { throw null; } static double System.Numerics.IUnaryNegationOperators<double, double>.operator checked -(double value) { throw null; } @@ -2266,7 +2275,6 @@ namespace System 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>(TOther value, out double result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, out double result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out double result) { throw null; } @@ -2736,7 +2744,6 @@ namespace System public static System.Half PositiveInfinity { get { throw null; } } static System.Half System.Numerics.IAdditiveIdentity<System.Half,System.Half>.AdditiveIdentity { get { throw null; } } static int System.Numerics.INumberBase<System.Half>.Radix { get { throw null; } } - static System.Half System.Numerics.ISignedNumber<System.Half>.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 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Half CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Half CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System 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 @@ namespace System static bool System.Numerics.INumberBase<System.Half>.IsComplexNumber(System.Half value) { throw null; } static bool System.Numerics.INumberBase<System.Half>.IsImaginaryNumber(System.Half value) { throw null; } static bool System.Numerics.INumberBase<System.Half>.IsZero(System.Half value) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertFromChecked<TOther>(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertFromSaturating<TOther>(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertFromTruncating<TOther>(TOther value, out System.Half result) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertToChecked<TOther>(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertToSaturating<TOther>(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Half>.TryConvertToTruncating<TOther>(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Half System.Numerics.ISubtractionOperators<System.Half, System.Half, System.Half>.operator checked -(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IUnaryNegationOperators<System.Half, System.Half>.operator checked -(System.Half value) { throw null; } public static System.Half Tan(System.Half x) { throw null; } @@ -2870,7 +2936,6 @@ namespace System 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>(TOther value, out System.Half result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Half result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, out System.Half result) { throw null; } @@ -3022,9 +3087,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Int128 CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.Int128 CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System 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 @@ namespace System 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 @@ namespace System 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 @@ namespace System static bool System.Numerics.INumberBase<System.Int128>.IsZero(System.Int128 value) { throw null; } static System.Int128 System.Numerics.INumberBase<System.Int128>.MaxMagnitudeNumber(System.Int128 x, System.Int128 y) { throw null; } static System.Int128 System.Numerics.INumberBase<System.Int128>.MinMagnitudeNumber(System.Int128 x, System.Int128 y) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertFromChecked<TOther>(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertFromSaturating<TOther>(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertFromTruncating<TOther>(TOther value, out System.Int128 result) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertToChecked<TOther>(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertToSaturating<TOther>(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.Int128>.TryConvertToTruncating<TOther>(System.Int128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.Int128 System.Numerics.INumber<System.Int128>.MaxNumber(System.Int128 x, System.Int128 y) { throw null; } static System.Int128 System.Numerics.INumber<System.Int128>.MinNumber(System.Int128 x, System.Int128 y) { throw null; } public override string ToString() { throw null; } @@ -3168,7 +3234,6 @@ namespace System 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>(TOther value, out System.Int128 result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Int128 result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out System.Int128 result) { throw null; } @@ -3195,9 +3260,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static short CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static short CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<short>.IsZero(short value) { throw null; } static short System.Numerics.INumberBase<short>.MaxMagnitudeNumber(short x, short y) { throw null; } static short System.Numerics.INumberBase<short>.MinMagnitudeNumber(short x, short y) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertFromChecked<TOther>(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertFromSaturating<TOther>(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertFromTruncating<TOther>(TOther value, out short result) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertToChecked<TOther>(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertToSaturating<TOther>(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<short>.TryConvertToTruncating<TOther>(short value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static short System.Numerics.INumber<short>.MaxNumber(short x, short y) { throw null; } static short System.Numerics.INumber<short>.MinNumber(short x, short y) { throw null; } static short System.Numerics.IShiftOperators<short, short>.operator <<(short value, int shiftAmount) { throw null; } @@ -3294,7 +3362,6 @@ namespace System 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>(TOther value, out short result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out short result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out short result) { throw null; } @@ -3321,9 +3388,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static int CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static int CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<int>.IsZero(int value) { throw null; } static int System.Numerics.INumberBase<int>.MaxMagnitudeNumber(int x, int y) { throw null; } static int System.Numerics.INumberBase<int>.MinMagnitudeNumber(int x, int y) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertFromChecked<TOther>(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertFromSaturating<TOther>(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertFromTruncating<TOther>(TOther value, out int result) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertToChecked<TOther>(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertToSaturating<TOther>(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<int>.TryConvertToTruncating<TOther>(int value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static int System.Numerics.INumber<int>.MaxNumber(int x, int y) { throw null; } static int System.Numerics.INumber<int>.MinNumber(int x, int y) { throw null; } static int System.Numerics.IShiftOperators<int, int>.operator <<(int value, int shiftAmount) { throw null; } @@ -3420,7 +3490,6 @@ namespace System 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>(TOther value, out int result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out int result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out int result) { throw null; } @@ -3447,9 +3516,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static long CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static long CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<long>.IsZero(long value) { throw null; } static long System.Numerics.INumberBase<long>.MaxMagnitudeNumber(long x, long y) { throw null; } static long System.Numerics.INumberBase<long>.MinMagnitudeNumber(long x, long y) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertFromChecked<TOther>(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertFromSaturating<TOther>(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertFromTruncating<TOther>(TOther value, out long result) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertToChecked<TOther>(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertToSaturating<TOther>(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<long>.TryConvertToTruncating<TOther>(long value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static long System.Numerics.INumber<long>.MaxNumber(long x, long y) { throw null; } static long System.Numerics.INumber<long>.MinNumber(long x, long y) { throw null; } static long System.Numerics.IShiftOperators<long, long>.operator <<(long value, int shiftAmount) { throw null; } @@ -3546,7 +3618,6 @@ namespace System 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>(TOther value, out long result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out long result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out long result) { throw null; } @@ -3580,9 +3651,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static nint CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static nint CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<nint>.IsZero(nint value) { throw null; } static nint System.Numerics.INumberBase<nint>.MaxMagnitudeNumber(nint x, nint y) { throw null; } static nint System.Numerics.INumberBase<nint>.MinMagnitudeNumber(nint x, nint y) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertFromChecked<TOther>(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertFromSaturating<TOther>(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertFromTruncating<TOther>(TOther value, out nint result) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertToChecked<TOther>(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertToSaturating<TOther>(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<nint>.TryConvertToTruncating<TOther>(nint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static nint System.Numerics.INumber<nint>.MaxNumber(nint x, nint y) { throw null; } static nint System.Numerics.INumber<nint>.MinNumber(nint x, nint y) { throw null; } static nint System.Numerics.IShiftOperators<nint, nint>.operator <<(nint value, int shiftAmount) { throw null; } @@ -3679,7 +3753,6 @@ namespace System 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>(TOther value, out nint result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out nint result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out nint result) { throw null; } @@ -4511,9 +4584,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static sbyte CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static sbyte CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<sbyte>.IsZero(sbyte value) { throw null; } static sbyte System.Numerics.INumberBase<sbyte>.MaxMagnitudeNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.INumberBase<sbyte>.MinMagnitudeNumber(sbyte x, sbyte y) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertFromChecked<TOther>(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertFromSaturating<TOther>(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertFromTruncating<TOther>(TOther value, out sbyte result) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertToChecked<TOther>(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertToSaturating<TOther>(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<sbyte>.TryConvertToTruncating<TOther>(sbyte value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static sbyte System.Numerics.INumber<sbyte>.MaxNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.INumber<sbyte>.MinNumber(sbyte x, sbyte y) { throw null; } static sbyte System.Numerics.IShiftOperators<sbyte, sbyte>.operator <<(sbyte value, int shiftAmount) { throw null; } @@ -4610,7 +4686,6 @@ namespace System 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>(TOther value, out sbyte result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out sbyte result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out sbyte result) { throw null; } @@ -4671,9 +4746,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static float CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static float CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static bool System.Numerics.INumberBase<float>.IsComplexNumber(float value) { throw null; } static bool System.Numerics.INumberBase<float>.IsImaginaryNumber(float value) { throw null; } static bool System.Numerics.INumberBase<float>.IsZero(float value) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertFromChecked<TOther>(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertFromSaturating<TOther>(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertFromTruncating<TOther>(TOther value, out float result) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertToChecked<TOther>(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertToSaturating<TOther>(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<float>.TryConvertToTruncating<TOther>(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static float System.Numerics.ISubtractionOperators<float, float, float>.operator checked -(float left, float right) { throw null; } static float System.Numerics.ISubtractionOperators<float, float, float>.operator -(float left, float right) { throw null; } static float System.Numerics.IUnaryNegationOperators<float, float>.operator checked -(float value) { throw null; } @@ -4796,7 +4874,6 @@ namespace System 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>(TOther value, out float result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out float result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out float result) { throw null; } @@ -5988,9 +6065,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.UInt128 CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static System.UInt128 CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System 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 @@ namespace System 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 @@ namespace System static System.UInt128 System.Numerics.INumberBase<System.UInt128>.MaxMagnitudeNumber(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumberBase<System.UInt128>.MinMagnitude(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumberBase<System.UInt128>.MinMagnitudeNumber(System.UInt128 x, System.UInt128 y) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertFromChecked<TOther>(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertFromSaturating<TOther>(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertFromTruncating<TOther>(TOther value, out System.UInt128 result) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertToChecked<TOther>(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertToSaturating<TOther>(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<System.UInt128>.TryConvertToTruncating<TOther>(System.UInt128 value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static System.UInt128 System.Numerics.INumber<System.UInt128>.CopySign(System.UInt128 value, System.UInt128 sign) { throw null; } static System.UInt128 System.Numerics.INumber<System.UInt128>.MaxNumber(System.UInt128 x, System.UInt128 y) { throw null; } static System.UInt128 System.Numerics.INumber<System.UInt128>.MinNumber(System.UInt128 x, System.UInt128 y) { throw null; } @@ -6142,7 +6220,6 @@ namespace System 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>(TOther value, out System.UInt128 result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.UInt128 result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out System.UInt128 result) { throw null; } @@ -6167,9 +6244,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static ushort CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static ushort CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static ushort System.Numerics.INumberBase<ushort>.MaxMagnitudeNumber(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumberBase<ushort>.MinMagnitude(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumberBase<ushort>.MinMagnitudeNumber(ushort x, ushort y) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertFromChecked<TOther>(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertFromSaturating<TOther>(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertFromTruncating<TOther>(TOther value, out ushort result) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertToChecked<TOther>(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertToSaturating<TOther>(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<ushort>.TryConvertToTruncating<TOther>(ushort value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static ushort System.Numerics.INumber<ushort>.CopySign(ushort value, ushort sign) { throw null; } static ushort System.Numerics.INumber<ushort>.MaxNumber(ushort x, ushort y) { throw null; } static ushort System.Numerics.INumber<ushort>.MinNumber(ushort x, ushort y) { throw null; } @@ -6268,7 +6348,6 @@ namespace System 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>(TOther value, out ushort result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out ushort result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out ushort result) { throw null; } @@ -6293,9 +6372,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static uint CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static uint CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static uint System.Numerics.INumberBase<uint>.MaxMagnitudeNumber(uint x, uint y) { throw null; } static uint System.Numerics.INumberBase<uint>.MinMagnitude(uint x, uint y) { throw null; } static uint System.Numerics.INumberBase<uint>.MinMagnitudeNumber(uint x, uint y) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertFromChecked<TOther>(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertFromSaturating<TOther>(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertFromTruncating<TOther>(TOther value, out uint result) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertToChecked<TOther>(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertToSaturating<TOther>(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<uint>.TryConvertToTruncating<TOther>(uint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static uint System.Numerics.INumber<uint>.CopySign(uint value, uint sign) { throw null; } static uint System.Numerics.INumber<uint>.MaxNumber(uint x, uint y) { throw null; } static uint System.Numerics.INumber<uint>.MinNumber(uint x, uint y) { throw null; } @@ -6394,7 +6476,6 @@ namespace System 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>(TOther value, out uint result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out uint result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out uint result) { throw null; } @@ -6419,9 +6500,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static ulong CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static ulong CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static ulong System.Numerics.INumberBase<ulong>.MaxMagnitudeNumber(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumberBase<ulong>.MinMagnitude(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumberBase<ulong>.MinMagnitudeNumber(ulong x, ulong y) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertFromChecked<TOther>(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertFromSaturating<TOther>(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertFromTruncating<TOther>(TOther value, out ulong result) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertToChecked<TOther>(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertToSaturating<TOther>(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<ulong>.TryConvertToTruncating<TOther>(ulong value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static ulong System.Numerics.INumber<ulong>.CopySign(ulong value, ulong sign) { throw null; } static ulong System.Numerics.INumber<ulong>.MaxNumber(ulong x, ulong y) { throw null; } static ulong System.Numerics.INumber<ulong>.MinNumber(ulong x, ulong y) { throw null; } @@ -6520,7 +6604,6 @@ namespace System 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>(TOther value, out ulong result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out ulong result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out ulong result) { throw null; } @@ -6551,9 +6634,6 @@ namespace System 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>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static nuint CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } - public static nuint CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { 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 @@ namespace System static nuint System.Numerics.INumberBase<nuint>.MaxMagnitudeNumber(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumberBase<nuint>.MinMagnitude(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumberBase<nuint>.MinMagnitudeNumber(nuint x, nuint y) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertFromChecked<TOther>(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertFromSaturating<TOther>(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertFromTruncating<TOther>(TOther value, out nuint result) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertToChecked<TOther>(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertToSaturating<TOther>(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } + static bool System.Numerics.INumberBase<nuint>.TryConvertToTruncating<TOther>(nuint value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static nuint System.Numerics.INumber<nuint>.CopySign(nuint value, nuint sign) { throw null; } static nuint System.Numerics.INumber<nuint>.MaxNumber(nuint x, nuint y) { throw null; } static nuint System.Numerics.INumber<nuint>.MinNumber(nuint x, nuint y) { throw null; } @@ -6649,7 +6735,6 @@ namespace System public uint ToUInt32() { throw null; } public ulong ToUInt64() { throw null; } public static nuint TrailingZeroCount(nuint value) { throw null; } - public static bool TryCreate<TOther>(TOther value, out nuint result) where TOther : System.Numerics.INumberBase<TOther> { throw null; } public bool TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>), System.IFormatProvider? provider = null) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out nuint result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out nuint result) { throw null; } @@ -10415,9 +10500,9 @@ namespace System.Numerics static abstract int Radix { get; } static abstract TSelf Zero { get; } static abstract TSelf Abs(TSelf value); - static abstract TSelf CreateChecked<TOther>(TOther value) where TOther : INumberBase<TOther>; - static abstract TSelf CreateSaturating<TOther>(TOther value) where TOther : INumberBase<TOther>; - static abstract TSelf CreateTruncating<TOther>(TOther value) where TOther : INumberBase<TOther>; + static virtual TSelf CreateChecked<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } + static virtual TSelf CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } + static virtual TSelf CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } static abstract bool IsCanonical(TSelf value); static abstract bool IsComplexNumber(TSelf value); static abstract bool IsEvenInteger(TSelf value); @@ -10441,7 +10526,12 @@ namespace System.Numerics static abstract TSelf MinMagnitudeNumber(TSelf x, TSelf y); static abstract TSelf Parse(System.ReadOnlySpan<char> 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>(TOther value, out TSelf result) where TOther : INumberBase<TOther>; + protected static abstract bool TryConvertFromChecked<TOther>(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase<TOther>; + protected static abstract bool TryConvertFromSaturating<TOther>(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase<TOther>; + protected static abstract bool TryConvertFromTruncating<TOther>(TOther value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TSelf? result) where TOther : System.Numerics.INumberBase<TOther>; + protected static abstract bool TryConvertToChecked<TOther>(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase<TOther>; + protected static abstract bool TryConvertToSaturating<TOther>(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase<TOther>; + protected static abstract bool TryConvertToTruncating<TOther>(TSelf value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther? result) where TOther : System.Numerics.INumberBase<TOther>; static abstract bool TryParse(System.ReadOnlySpan<char> 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 2d5262e7145..0c30d246fd6 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 @@ -587,6 +588,66 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<double>(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<double>(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<double>(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<double>(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<double>(+255.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(+256.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<Half>(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<Half>((Half)255.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.NegativeOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>((Half)256.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<short>(0x0000)); @@ -617,6 +678,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +709,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<NFloat>(+255.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(+256.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<sbyte>(0x00)); @@ -648,6 +743,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<float>(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<float>(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<float>(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<float>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateChecked<float>(+255.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(+256.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<ushort>(0x0000)); @@ -678,6 +797,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<byte>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +848,66 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<double>(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<double>(+255.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(-1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<double>(+256.0)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Half>((Half)255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.NegativeOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Half>((Half)256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<short>(0x0000)); @@ -749,6 +938,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +969,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<NFloat>(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<NFloat>(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +1003,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<float>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<float>(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<float>(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1057,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1108,66 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(+0.0)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(-0.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(+double.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<double>(+1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<double>(+255.0)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(-1.0)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<double>(+256.0)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Half>((Half)255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.NegativeOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Half>((Half)256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<short>(0x0000)); @@ -881,6 +1198,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1229,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<NFloat>(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<NFloat>(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1263,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(+0.0f)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(+float.Epsilon)); + + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<float>(+1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<float>(+255.0f)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(-1.0f)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<float>(+256.0f)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1317,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((byte)0x01, NumberBaseHelper<byte>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((byte)0x00, NumberBaseHelper<byte>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((byte)0xFF, NumberBaseHelper<byte>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1557,6 @@ namespace System.Tests Assert.Equal((byte)0x01, NumberBaseHelper<byte>.MinMagnitudeNumber((byte)0xFF, (byte)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<byte>(0x00, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<byte>(0x01, out result)); - Assert.Equal((byte)0x01, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((byte)0x7F, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<byte>(0x80, out result)); - Assert.Equal((byte)0x80, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((byte)0xFF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<short>(0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<short>(0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - byte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper<byte>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((byte)0x01, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((byte)0x7F, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - byte result; - - Assert.True(NumberBaseHelper<byte>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - byte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((byte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper<byte>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((byte)0x00, result); - - Assert.True(NumberBaseHelper<byte>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((byte)0x01, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((byte)0x00, result); - - Assert.False(NumberBaseHelper<byte>.TryCreate<nuint>(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 f471e17249f..3c33ae7a37e 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 @@ -586,6 +587,64 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((char)0x00, NumberBaseHelper<char>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((char)0x00, NumberBaseHelper<char>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((char)0x01, NumberBaseHelper<char>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<double>(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<double>(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<double>(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<double>(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateChecked<double>(+65535.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(+65536.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<Half>(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper<char>.CreateChecked<Half>(Half.MaxValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Half>(Half.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<short>(0x0000)); @@ -616,6 +675,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -637,6 +706,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateChecked<NFloat>(65535.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(+65536.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<sbyte>(0x00)); @@ -647,6 +740,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<float>(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<float>(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<float>(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateChecked<float>(+65535.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(+65536.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<ushort>(0x0000)); @@ -677,6 +794,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<char>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -718,6 +845,64 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<double>(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<double>(+65535.0)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(-1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<double>(+65536.0)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<Half>(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper<char>.CreateSaturating<Half>(Half.MaxValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<short>(0x0000)); @@ -748,6 +933,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -769,6 +964,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<NFloat>(65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<NFloat>(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<sbyte>(0x00)); @@ -779,6 +998,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<float>(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<float>(+65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<float>(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<ushort>(0x0000)); @@ -809,6 +1052,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -850,6 +1103,64 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(+0.0)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(-0.0)); + + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(+double.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<double>(+1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<double>(+65535.0)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(-1.0)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<double>(+65536.0)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<Half>(Half.One)); + Assert.Equal((char)0xFFE0, NumberBaseHelper<char>.CreateTruncating<Half>(Half.MaxValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.MinValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<short>(0x0000)); @@ -880,6 +1191,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -901,6 +1222,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<NFloat>(65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<NFloat>(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<sbyte>(0x00)); @@ -911,6 +1256,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(+0.0f)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<float>(+1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<float>(+65535.0f)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(-1.0f)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<float>(+65536.0f)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<ushort>(0x0000)); @@ -941,6 +1310,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((char)0x0001, NumberBaseHelper<char>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((char)0x0000, NumberBaseHelper<char>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((char)0xFFFF, NumberBaseHelper<char>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1171,277 +1550,6 @@ namespace System.Tests Assert.Equal((char)0x0001, NumberBaseHelper<char>.MinMagnitudeNumber((char)0xFFFF, (char)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<byte>(0x00, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<byte>(0x01, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((char)0x007F, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<byte>(0x80, out result)); - Assert.Equal((char)0x0080, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((char)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((char)0x8000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((char)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<short>(0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<short>(0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - char result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper<char>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((char)0x007F, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((char)0x7FFF, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((char)0x8000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((char)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - char result; - - Assert.True(NumberBaseHelper<char>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - char result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((char)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper<char>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((char)0x0000, result); - - Assert.True(NumberBaseHelper<char>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((char)0x0001, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((char)0x0000, result); - - Assert.False(NumberBaseHelper<char>.TryCreate<nuint>(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 f49ce0c7c94..86dad1e6b1a 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 @@ -585,6 +586,65 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<decimal>(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateChecked<decimal>(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateChecked<decimal>(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<decimal>(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<double>(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<double>(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<double>(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<double>(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<double>(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<double>(-79228162514264333195497439231.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(+79228162514264337593543950335.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(-79228162514264337593543950335.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper<decimal>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper<decimal>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper<decimal>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<short>(0x0000)); @@ -647,6 +707,27 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<NFloat>(-1.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<sbyte>(0x00)); @@ -657,6 +738,33 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<float>(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<float>(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateChecked<float>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateChecked<float>(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<float>(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateChecked<float>(-79228160000000000000000000000.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(+79228162514264337593543950335.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(-79228162514264337593543950335.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<decimal>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateChecked<ushort>(0x0000)); @@ -739,6 +847,65 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<decimal>(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<decimal>(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateSaturating<double>(-79228162514264333195497439231.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<double>(+79228162514264337593543950335.0)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<double>(-79228162514264337593543950335.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper<decimal>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper<decimal>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<short>(0x0000)); @@ -802,6 +969,27 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(-1.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<sbyte>(0x00)); @@ -812,6 +1000,33 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateSaturating<float>(-79228160000000000000000000000.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<float>(+79228162514264337593543950335.0f)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<float>(-79228162514264337593543950335.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateSaturating<ushort>(0x0000)); @@ -895,6 +1110,65 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<decimal>(-1.0m)); + Assert.Equal(-0.0m, NumberBaseHelper<decimal>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal(+0.0m, NumberBaseHelper<decimal>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<decimal>(+1.0m)); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(+0.0)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(-0.0)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(+1.0)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(-1.0)); + + Assert.Equal(+79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(+79228162514264333195497439231.0)); + Assert.Equal(-79228162514264300000000000000.0m, NumberBaseHelper<decimal>.CreateTruncating<double>(-79228162514264333195497439231.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<double>(+79228162514264337593543950335.0)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<double>(-79228162514264337593543950335.0)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal(+0.00000005960464m, NumberBaseHelper<decimal>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal(-0.00000005960464m, NumberBaseHelper<decimal>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.One)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal(+65504.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(-65504.0m, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<short>(0x0000)); @@ -933,7 +1207,7 @@ namespace System.Tests Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); - Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); } [Fact] @@ -958,6 +1232,27 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(-1.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<sbyte>(0x00)); @@ -968,6 +1263,33 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(+0.0f)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(-0.0f)); + + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal(+1.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(+1.0f)); + Assert.Equal(-1.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(-1.0f)); + + Assert.Equal(+79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(+79228160000000000000000000000.0f)); + Assert.Equal(-79228160000000000000000000000.0m, NumberBaseHelper<decimal>.CreateTruncating<float>(-79228160000000000000000000000.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<float>(+79228162514264337593543950335.0f)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<float>(-79228162514264337593543950335.0f)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(decimal.MinValue, NumberBaseHelper<decimal>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal(decimal.Zero, NumberBaseHelper<decimal>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<ushort>(0x0000)); @@ -1006,7 +1328,7 @@ namespace System.Tests Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))); - Assert.Equal(0.0m, NumberBaseHelper<decimal>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); + Assert.Equal(decimal.MaxValue, NumberBaseHelper<decimal>.CreateTruncating<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000))); } [Fact] @@ -1371,319 +1693,6 @@ namespace System.Tests Assert.Equal(1.0m, NumberBaseHelper<decimal>.MinMagnitudeNumber(decimal.MaxValue, 1.0m)); } - [Fact] - public static void TryCreateFromByteTest() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<byte>(0x00, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<byte>(0x01, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(127.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<byte>(0x80, out result)); - Assert.Equal(128.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(255.0m, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(32768.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(65535.0m, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<short>(0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<short>(0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<Int128>(new Int128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(-1.0m, result); - - Assert.False(NumberBaseHelper<decimal>.TryCreate<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper<decimal>.TryCreate<Int128>(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<decimal>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - else - { - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0m, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(127.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0m, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(32767.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(32768.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(65535.0m, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(2147483648.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0m, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0m, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - decimal result; - - Assert.True(NumberBaseHelper<decimal>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0m, result); - - Assert.False(NumberBaseHelper<decimal>.TryCreate<UInt128>(new UInt128(0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper<decimal>.TryCreate<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(0.0m, result); - - Assert.False(NumberBaseHelper<decimal>.TryCreate<UInt128>(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<decimal>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(9223372036854775808.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(18446744073709551615.0m, result); - } - else - { - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(0.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(1.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal(2147483648.0m, result); - - Assert.True(NumberBaseHelper<decimal>.TryCreate<nuint>(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 f0868228a67..a1bae12e927 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) { @@ -1040,6 +1041,69 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<double>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateChecked<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateChecked<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateChecked<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateChecked<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<double>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateChecked<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateChecked<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateChecked<double>(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateChecked<double>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateChecked<double>(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateChecked<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateChecked<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateChecked<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateChecked<double>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateChecked<double>(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateChecked<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateChecked<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateChecked<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateChecked<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<double>.CreateChecked<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<double>.CreateChecked<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<double>.CreateChecked<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<double>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<double>.CreateChecked<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<double>.CreateChecked<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<double>.CreateChecked<Half>(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateChecked<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateChecked<short>(0x0000)); @@ -1101,6 +1165,49 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateChecked<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateChecked<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateChecked<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateChecked<NFloat>(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateChecked<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateChecked<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateChecked<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateChecked<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateChecked<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateChecked<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateChecked<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateChecked<NFloat>(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateChecked<sbyte>(0x00)); @@ -1111,6 +1218,32 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateChecked<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateChecked<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateChecked<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateChecked<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateChecked<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateChecked<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateChecked<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateChecked<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateChecked<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateChecked<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateChecked<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateChecked<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateChecked<float>(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateChecked<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateChecked<ushort>(0x0000)); @@ -1196,6 +1329,69 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<double>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateSaturating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateSaturating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateSaturating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateSaturating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<double>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateSaturating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateSaturating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateSaturating<double>(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateSaturating<double>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateSaturating<double>(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateSaturating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateSaturating<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateSaturating<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateSaturating<double>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateSaturating<double>(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateSaturating<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateSaturating<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateSaturating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateSaturating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<double>.CreateSaturating<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<double>.CreateSaturating<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<double>.CreateSaturating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<double>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<double>.CreateSaturating<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<double>.CreateSaturating<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<double>.CreateSaturating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateSaturating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateSaturating<short>(0x0000)); @@ -1257,6 +1453,49 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateSaturating<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateSaturating<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateSaturating<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateSaturating<NFloat>(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateSaturating<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateSaturating<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateSaturating<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateSaturating<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateSaturating<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateSaturating<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateSaturating<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateSaturating<NFloat>(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateSaturating<sbyte>(0x00)); @@ -1267,6 +1506,32 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateSaturating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateSaturating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateSaturating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateSaturating<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateSaturating<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateSaturating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateSaturating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateSaturating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateSaturating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateSaturating<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateSaturating<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateSaturating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateSaturating<float>(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateSaturating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateSaturating<ushort>(0x0000)); @@ -1352,6 +1617,69 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0, NumberBaseHelper<double>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateTruncating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateTruncating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateTruncating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateTruncating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper<double>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateTruncating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateTruncating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateTruncating<double>(-1.0)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateTruncating<double>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateTruncating<double>(-MaxSubnormal)); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateTruncating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateTruncating<double>(-0.0)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateTruncating<double>(+0.0)); + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateTruncating<double>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateTruncating<double>(MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateTruncating<double>(1.0)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateTruncating<double>(double.MaxValue)); + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateTruncating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateTruncating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.103515625E-05, NumberBaseHelper<double>.CreateTruncating<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555160522461E-05, NumberBaseHelper<double>.CreateTruncating<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.960464477539063E-08, NumberBaseHelper<double>.CreateTruncating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.960464477539063E-08, NumberBaseHelper<double>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555160522461E-05, NumberBaseHelper<double>.CreateTruncating<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.103515625E-05, NumberBaseHelper<double>.CreateTruncating<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0, NumberBaseHelper<double>.CreateTruncating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateTruncating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateTruncating<short>(0x0000)); @@ -1413,6 +1741,49 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateTruncating<NFloat>(-1.0f)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateTruncating<NFloat>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateTruncating<NFloat>(+0.0f)); + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateTruncating<NFloat>(1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(double.MinValue, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<double>.CreateTruncating<NFloat>((NFloat)(-MinNormal))); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<double>.CreateTruncating<NFloat>((NFloat)(-MaxSubnormal))); + AssertBitwiseEqual(-double.Epsilon, NumberBaseHelper<double>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+double.Epsilon, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<double>.CreateTruncating<NFloat>((NFloat)MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<double>.CreateTruncating<NFloat>((NFloat)MinNormal)); + + AssertBitwiseEqual(double.MaxValue, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.MinValue)); + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateTruncating<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateTruncating<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateTruncating<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateTruncating<NFloat>(SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateTruncating<sbyte>(0x00)); @@ -1423,6 +1794,32 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(double.NegativeInfinity, NumberBaseHelper<double>.CreateTruncating<float>(float.NegativeInfinity)); + + AssertBitwiseEqual(-3.4028234663852886E+38, NumberBaseHelper<double>.CreateTruncating<float>(float.MinValue)); + AssertBitwiseEqual(-1.0, NumberBaseHelper<double>.CreateTruncating<float>(-1.0f)); + + AssertBitwiseEqual(-1.1754943508222875E-38, NumberBaseHelper<double>.CreateTruncating<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-1.1754942106924411E-38, NumberBaseHelper<double>.CreateTruncating<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-1.401298464324817E-45, NumberBaseHelper<double>.CreateTruncating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0, NumberBaseHelper<double>.CreateTruncating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0, NumberBaseHelper<double>.CreateTruncating<float>(+0.0f)); + AssertBitwiseEqual(+1.401298464324817E-45, NumberBaseHelper<double>.CreateTruncating<float>(float.Epsilon)); + AssertBitwiseEqual(+1.1754942106924411E-38, NumberBaseHelper<double>.CreateTruncating<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+1.1754943508222875E-38, NumberBaseHelper<double>.CreateTruncating<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0, NumberBaseHelper<double>.CreateTruncating<float>(1.0f)); + AssertBitwiseEqual(+3.4028234663852886E+38, NumberBaseHelper<double>.CreateTruncating<float>(float.MaxValue)); + + AssertBitwiseEqual(double.PositiveInfinity, NumberBaseHelper<double>.CreateTruncating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(double.NaN, NumberBaseHelper<double>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { AssertBitwiseEqual(0.0, NumberBaseHelper<double>.CreateTruncating<ushort>(0x0000)); @@ -1907,321 +2304,6 @@ namespace System.Tests AssertBitwiseEqual(1.0, NumberBaseHelper<double>.MinMagnitudeNumber(double.PositiveInfinity, 1.0)); } - [Fact] - public static void TryCreateFromByteTest() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<byte>(0x00, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<byte>(0x01, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(127.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<byte>(0x80, out result)); - Assert.Equal(128.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(255.0, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(32768.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(65535.0, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<short>(0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<short>(0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(-170141183460469231731687303715884105728.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<Int128>(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<double>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - else - { - Assert.True(NumberBaseHelper<double>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(127.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(32767.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(32768.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(65535.0, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(2147483648.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - double result; - - Assert.True(NumberBaseHelper<double>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(170141183460469231731687303715884105728.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<UInt128>(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<double>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0, result); - // - // Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0, result); - } - else - { - Assert.True(NumberBaseHelper<double>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(0.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(1.0, result); - - Assert.True(NumberBaseHelper<double>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0, result); - // - // Assert.True(NumberBaseHelper<double>.TryCreate<nuint>(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 c3d521808c3..4ef1474efc6 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) { @@ -1058,6 +1059,70 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<decimal>(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateChecked<decimal>(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateChecked<decimal>(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper<Half>.CreateChecked<decimal>(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<double>(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<double>(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<double>(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<double>(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<double>(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<double>(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateChecked<double>(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<double>(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<Half>(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper<Half>.CreateChecked<Half>(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<Half>.CreateChecked<Half>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<Half>.CreateChecked<Half>(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper<Half>.CreateChecked<Half>(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateChecked<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateChecked<Half>(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper<Half>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper<Half>.CreateChecked<Half>(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper<Half>.CreateChecked<Half>(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateChecked<Half>(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper<Half>.CreateChecked<Half>(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<short>(0x0000)); @@ -1119,6 +1184,47 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<NFloat>(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateChecked<NFloat>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<sbyte>(0x00)); @@ -1129,6 +1235,32 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<float>(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateChecked<float>(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateChecked<float>(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<float>(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateChecked<float>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<float>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<float>(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateChecked<float>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<float>(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateChecked<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateChecked<ushort>(0x0000)); @@ -1214,6 +1346,70 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<decimal>(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateSaturating<decimal>(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateSaturating<decimal>(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper<Half>.CreateSaturating<decimal>(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<double>(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<double>(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<double>(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<double>(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<double>(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateSaturating<double>(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<double>(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<Half>.CreateSaturating<Half>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<Half>.CreateSaturating<Half>(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper<Half>.CreateSaturating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper<Half>.CreateSaturating<Half>(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper<Half>.CreateSaturating<Half>(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<short>(0x0000)); @@ -1275,6 +1471,47 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<NFloat>(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateSaturating<NFloat>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<sbyte>(0x00)); @@ -1285,6 +1522,32 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<float>(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateSaturating<float>(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateSaturating<float>(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<float>(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateSaturating<float>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<float>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<float>(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateSaturating<float>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<float>(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateSaturating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateSaturating<ushort>(0x0000)); @@ -1370,6 +1633,70 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<decimal>(-1.0m)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateTruncating<decimal>(-0.0m)); + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateTruncating<decimal>(+0.0m)); + AssertBitwiseEqual(Half.One, NumberBaseHelper<Half>.CreateTruncating<decimal>(+1.0m)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<double>(double.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<double>(-1.0)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<double>(-double.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<double>(-0.0)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<double>(+0.0)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateTruncating<double>(1.0)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<double>(double.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.NegativeInfinity)); + AssertBitwiseEqual(Half.MinValue, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<Half>.CreateTruncating<Half>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<Half>.CreateTruncating<Half>(-MaxSubnormal)); + AssertBitwiseEqual(-Half.Epsilon, NumberBaseHelper<Half>.CreateTruncating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(Half.NegativeZero, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(Half.Zero, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.Zero)); + AssertBitwiseEqual(Half.Epsilon, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual(MaxSubnormal, NumberBaseHelper<Half>.CreateTruncating<Half>(MaxSubnormal)); + AssertBitwiseEqual(MinNormal, NumberBaseHelper<Half>.CreateTruncating<Half>(MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.One)); + + AssertBitwiseEqual(Half.MaxValue, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<short>(0x0000)); @@ -1431,6 +1758,47 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + } + else + { + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<NFloat>(SingleTests_GenericMath.MinNormal)); + } + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateTruncating<NFloat>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<sbyte>(0x00)); @@ -1441,6 +1809,32 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<float>(float.NegativeInfinity)); + AssertBitwiseEqual(Half.NegativeInfinity, NumberBaseHelper<Half>.CreateTruncating<float>(float.MinValue)); + + AssertBitwiseEqual(Half.NegativeOne, NumberBaseHelper<Half>.CreateTruncating<float>(-1.0f)); + + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<float>(-SingleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<float>(-SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<float>(-float.Epsilon)); + AssertBitwiseEqual(NegativeZero, NumberBaseHelper<Half>.CreateTruncating<float>(-0.0f)); + + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<float>(+0.0f)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<float>(float.Epsilon)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<float>(SingleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<float>(SingleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(One, NumberBaseHelper<Half>.CreateTruncating<float>(1.0f)); + + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<float>(float.MaxValue)); + AssertBitwiseEqual(Half.PositiveInfinity, NumberBaseHelper<Half>.CreateTruncating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(Half.NaN, NumberBaseHelper<Half>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { AssertBitwiseEqual(Zero, NumberBaseHelper<Half>.CreateTruncating<ushort>(0x0000)); @@ -1925,321 +2319,6 @@ namespace System.Tests AssertBitwiseEqual(One, NumberBaseHelper<Half>.MinMagnitudeNumber(Half.PositiveInfinity, One)); } - [Fact] - public static void TryCreateFromByteTest() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<byte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<byte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((Half)127.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<byte>(0x80, out result)); - Assert.Equal((Half)128.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((Half)255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((Half)32768.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((Half)65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<short>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<short>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((Half)(-32768.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((Half)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal((Half)(-9223372036854775808.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal((Half)170141183460469231731687303715884105727.0, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal((Half)(-170141183460469231731687303715884105728.0), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<Int128>(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<Half>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((Half)(-9223372036854775808.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((Half)(-2147483648.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((Half)127.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((Half)(-128.0f), result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((Half)32767.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((Half)32768.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((Half)65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((Half)2147483648.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((Half)4294967295.0f, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((Half)9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((Half)18446744073709551615.0f, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - Half result; - - Assert.True(NumberBaseHelper<Half>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal((Half)170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal((Half)170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<UInt128>(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<Half>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((Half)9223372036854775807.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal((Half)9223372036854775808.0f, result); - // - // Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal((Half)18446744073709551615.0f, result); - } - else - { - Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((Half)2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - // Assert.Equal((Half)2147483648.0f, result); - // - // Assert.True(NumberBaseHelper<Half>.TryCreate<nuint>(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 fd057cbb484..9b71f495ee6 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 @@ namespace System.Tests Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<double>(double.PositiveInfinity)); Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<double>(double.NaN)); } [Fact] @@ -725,6 +728,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -746,6 +759,48 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<Int128>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateChecked<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<NFloat>((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<NFloat>((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateChecked<NFloat>((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<NFloat>(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateChecked<NFloat>(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateChecked<NFloat>(-170141183460469231731687303715884105728.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(-170141203742878835383357727663135391744.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<sbyte>(0x00)); @@ -813,6 +868,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateChecked<UInt128>(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<Int128>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -941,6 +1006,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -962,6 +1037,48 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateSaturating<NFloat>((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateSaturating<NFloat>((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateSaturating<NFloat>(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-170141183460469231731687303715884105728.0f)); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(-170141203742878835383357727663135391744.0f)); + } + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<sbyte>(0x00)); @@ -1028,6 +1145,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1156,6 +1283,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1177,6 +1314,48 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal(One, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateTruncating<NFloat>((NFloat)(+170141183460469212842221372237303250944.0))); + Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateTruncating<NFloat>((NFloat)(-170141183460469212842221372237303250944.0))); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>((NFloat)(-170141183460469231731687303715884105728.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>((NFloat)(-170141183460469269510619166673045815296.0))); + } + else + { + Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateTruncating<NFloat>(+170141173319264429905852091742258462720.0f)); + Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-170141173319264429905852091742258462720.0f)); + + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-170141183460469231731687303715884105728.0f)); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(-170141203742878835383357727663135391744.0f)); + } + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<sbyte>(0x00)); @@ -1243,6 +1422,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<Int128>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<Int128>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(MaxValue, NumberBaseHelper<Int128>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(MinValue, NumberBaseHelper<Int128>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1473,436 +1662,6 @@ namespace System.Tests Assert.Equal(NegativeOne, NumberBaseHelper<Int128>.MinMagnitudeNumber(NegativeOne, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<byte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<byte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<byte>(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromDecimalTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<decimal>(decimal.Zero, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<decimal>(decimal.One, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<decimal>(decimal.MinusOne, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<decimal>(decimal.MaxValue, out result)); - Assert.Equal(new Int128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<decimal>(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<Int128>.TryCreate<double>(+0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(-0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(+double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(-double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(+1.0, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(-1.0, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(+170141183460469212842221372237303250944.0, out result)); - Assert.Equal(new Int128(0x7FFF_FFFF_FFFF_FC00, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(-170141183460469212842221372237303250944.0, out result)); - Assert.Equal(new Int128(0x8000_0000_0000_0400, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<double>(-170141183460469231731687303715884105728.0, out result)); - Assert.Equal(MinValue, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(+170141183460469231731687303715884105728.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(-170141183460469269510619166673045815296.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(double.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(double.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(double.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<double>(double.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromHalfTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>((Half)(+0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>((Half)(-0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>(+Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>(-Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>((Half)(+1.0), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>((Half)(-1.0), out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>(Half.MaxValue, out result)); - Assert.Equal(+65504, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<Half>(Half.MinValue, out result)); - Assert.Equal(-65504, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<Half>(Half.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<Half>(Half.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<short>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<short>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(Int16MinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - Int128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Int64MinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - else - { - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(Int32MinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(NegativeOne, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(SByteMinValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(NegativeOne, result); - } - - [Fact] - public static void TryCreateFromSingleTest() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(+0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(-0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(+float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(-float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(+1.0f, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(-1.0f, out result)); - Assert.Equal(NegativeOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(+170141173319264429905852091742258462720.0f, out result)); - Assert.Equal(new Int128(0x7FFF_FF80_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(-170141173319264429905852091742258462720.0f, out result)); - Assert.Equal(new Int128(0x8000_0080_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<float>(-170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(MinValue, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(+170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(-170141203742878835383357727663135391744.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(float.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(float.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(float.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<Int128>.TryCreate<float>(float.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - Int128 result; - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - Int128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<Int128>.TryCreate<nuint>(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 a2ca19cf854..e869a8259e9 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 @@ -587,6 +588,69 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<decimal>(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<decimal>(-1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<double>(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<double>(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<double>(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<double>(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateChecked<double>(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<double>(-32768.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(+32768.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(-32769.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<Half>(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper<short>.CreateChecked<Half>((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<Half>((Half)(-32768.0f))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>((Half)32768.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>((Half)(-32800.0f))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>(Half.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<short>(0x0000)); @@ -617,6 +681,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +712,31 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<NFloat>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateChecked<NFloat>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<NFloat>(-32768.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(+32768.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(-32769.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<sbyte>(0x00)); @@ -648,6 +747,31 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<float>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<float>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<float>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateChecked<float>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateChecked<float>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateChecked<float>(-32768.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(+32768.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(-32769.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<ushort>(0x0000)); @@ -678,6 +802,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<short>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +853,69 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<decimal>(-1.0m)); + + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<double>(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<double>(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<double>(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<double>(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateSaturating<double>(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<double>(-32768.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<double>(+32768.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<double>(-32769.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<Half>(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper<short>.CreateSaturating<Half>((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Half>((Half)(-32768.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<Half>((Half)32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Half>((Half)(-32800.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<short>(0x0000)); @@ -749,6 +946,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +977,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<NFloat>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateSaturating<NFloat>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<NFloat>(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<NFloat>(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<NFloat>(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +1012,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<float>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<float>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateSaturating<float>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<float>(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<float>(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<float>(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateSaturating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1067,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1118,69 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<decimal>(-1.0m)); + + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<double>(+0.0)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<double>(-0.0)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<double>(+1.0)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<double>(-1.0)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateTruncating<double>(+32767.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<double>(-32768.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<double>(+32768.0)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<double>(-32769.0)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<Half>(Half.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((short)0x7FF0, NumberBaseHelper<short>.CreateTruncating<Half>((Half)32752.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<Half>((Half)(-32768.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<Half>((Half)32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<Half>((Half)(-32800.0f))); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<short>(0x0000)); @@ -881,6 +1211,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((short)0x0000), NumberBaseHelper<short>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1242,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<NFloat>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateTruncating<NFloat>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<NFloat>(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<NFloat>(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<NFloat>(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1277,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<float>(+0.0f)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<float>(+1.0f)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((short)0x7FFF, NumberBaseHelper<short>.CreateTruncating<float>(+32767.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<float>(-32768.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<float>(+32768.0f)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<float>(-32769.0f)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(unchecked((short)0x7FFF), NumberBaseHelper<short>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((short)0x8000), NumberBaseHelper<short>.CreateTruncating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1332,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((short)0x0000, NumberBaseHelper<short>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((short)0x0001, NumberBaseHelper<short>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((short)0x0000), NumberBaseHelper<short>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1572,6 @@ namespace System.Tests Assert.Equal(unchecked((short)0xFFFF), NumberBaseHelper<short>.MinMagnitudeNumber(unchecked((short)0xFFFF), (short)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<byte>(0x00, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<byte>(0x01, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((short)0x007F, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<byte>(0x80, out result)); - Assert.Equal((short)0x0080, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((short)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<short>(0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<short>(0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((short)0x8000), result); - - Assert.True(NumberBaseHelper<short>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - short result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<short>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((short)0x007F, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((short)0xFF80), result); - - Assert.True(NumberBaseHelper<short>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((short)0xFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((short)0x7FFF, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - short result; - - Assert.True(NumberBaseHelper<short>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - short result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((short)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper<short>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((short)0x0000, result); - - Assert.True(NumberBaseHelper<short>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((short)0x0001, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((short)0x0000, result); - - Assert.False(NumberBaseHelper<short>.TryCreate<nuint>(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 4246afdda0f..073580354b8 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 @@ -587,6 +588,63 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<decimal>(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<decimal>(-1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<double>(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<double>(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<double>(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<double>(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateChecked<double>(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateChecked<double>(-2147483648.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(+2147483648.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(-2147483649.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<Half>(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper<int>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper<int>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateChecked<short>(0x0000)); @@ -617,6 +675,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +706,42 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateChecked<NFloat>((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateChecked<NFloat>((NFloat)(-2147483648.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>((NFloat)(+2147483648.0))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateChecked<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateChecked<NFloat>(-2147483648.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(+2147483647.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(-2147483904.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateChecked<sbyte>(0x00)); @@ -648,6 +752,31 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<float>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<float>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<float>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateChecked<float>(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateChecked<float>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateChecked<float>(-2147483648.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(+2147483648.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(-2147483904.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateChecked<ushort>(0x0000)); @@ -678,6 +807,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<int>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +858,63 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<decimal>(-1.0m)); + + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<double>(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<double>(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<double>(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<double>(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<double>(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<double>(-2147483648.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<double>(+2147483648.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<double>(-2147483649.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<Half>(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper<int>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper<int>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateSaturating<short>(0x0000)); @@ -749,6 +945,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +976,42 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<NFloat>((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>((NFloat)(-2147483648.0))); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<NFloat>((NFloat)(+2147483648.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateSaturating<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FF80), NumberBaseHelper<int>.CreateSaturating<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>(-2147483904.0f)); + } + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +1022,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<float>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<float>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateSaturating<float>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<float>(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<float>(+2147483648.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<float>(-2147483904.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateSaturating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1077,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1128,63 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<decimal>(-1.0m)); + + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<double>(+0.0)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<double>(-0.0)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<double>(+1.0)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<double>(-1.0)); + + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateTruncating<double>(+2147483647.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<double>(-2147483648.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<double>(+2147483648.0)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<double>(-2147483649.0)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<Half>(Half.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((int)0x0000_FFE0, NumberBaseHelper<int>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((int)0xFFFF_0020), NumberBaseHelper<int>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateTruncating<short>(0x0000)); @@ -881,6 +1215,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper<int>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1246,42 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((int)0x7FFF_FFFF, NumberBaseHelper<int>.CreateTruncating<NFloat>((NFloat)(+2147483647.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>((NFloat)(-2147483648.0))); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<NFloat>((NFloat)(+2147483648.0))); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>((NFloat)(-2147483649.0))); + } + else + { + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateTruncating<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<NFloat>(+2147483647.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>(-2147483904.0f)); + } + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1292,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<float>(+0.0f)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal((int)0x0000_0000, NumberBaseHelper<int>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((int)0x0000_0001, NumberBaseHelper<int>.CreateTruncating<float>(+1.0f)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((int)0x7FFF_FF80, NumberBaseHelper<int>.CreateTruncating<float>(+2147483520.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<float>(-2147483648.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<float>(+2147483648.0f)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<float>(-2147483904.0f)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(unchecked((int)0x7FFF_FFFF), NumberBaseHelper<int>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((int)0x8000_0000), NumberBaseHelper<int>.CreateTruncating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((int)0x00000000, NumberBaseHelper<int>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1347,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper<int>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(unchecked((int)0x0000_0001), NumberBaseHelper<int>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((int)0x0000_0000), NumberBaseHelper<int>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((int)0xFFFF_FFFF), NumberBaseHelper<int>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1587,6 @@ namespace System.Tests Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper<int>.MinMagnitudeNumber(unchecked((int)0xFFFFFFFF), 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<byte>(0x00, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<byte>(0x01, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((int)0x0000007F, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<byte>(0x80, out result)); - Assert.Equal((int)0x00000080, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((int)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((int)0x00008000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((int)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<short>(0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<short>(0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((int)0xFFFF8000), result); - - Assert.True(NumberBaseHelper<int>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<int>(unchecked(unchecked((int)0x80000000)), out result)); - Assert.Equal(unchecked((int)0x80000000), result); - - Assert.True(NumberBaseHelper<int>.TryCreate<int>(unchecked(unchecked((int)0xFFFFFFFF)), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - int result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<int>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(unchecked((int)0x80000000), result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((int)0x0000007F, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((int)0xFFFFFF80), result); - - Assert.True(NumberBaseHelper<int>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((int)0x00007FFF, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((int)0x00008000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((int)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(unchecked((int)0x00000000), result); - - Assert.False(NumberBaseHelper<int>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(unchecked((int)0x00000000), result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - int result; - - Assert.True(NumberBaseHelper<int>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((int)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - int result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((int)0x00000001, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((int)0x00000000, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((int)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper<int>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((int)0x00000000, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((int)0x00000001, result); - - Assert.True(NumberBaseHelper<int>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((int)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal(unchecked((int)0x00000000), result); - - Assert.False(NumberBaseHelper<int>.TryCreate<nuint>(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 bced25ea607..831349298dd 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 @@ -587,6 +588,64 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<decimal>(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<decimal>(-1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<double>(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<double>(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<double>(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<double>(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateChecked<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateChecked<double>(-9223372036854775808.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(+9223372036854775808.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(-9223372036854777856.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<Half>(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper<long>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<long>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateChecked<short>(0x0000)); @@ -617,6 +676,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +707,43 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateChecked<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateChecked<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateChecked<float>(-9223372036854775808.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(+9223372036854775808.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(-9223373136366403584.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateChecked<sbyte>(0x00)); @@ -648,6 +754,32 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<float>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateChecked<float>(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateChecked<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateChecked<float>(-9223372036854775808.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(+9223372036854775808.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(-9223373136366403584.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateChecked<ushort>(0x0000)); @@ -678,6 +810,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<long>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +861,63 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<decimal>(-1.0m)); + + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<double>(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<double>(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<double>(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<double>(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateSaturating<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<double>(-9223372036854775808.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<double>(+9223372036854775808.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<double>(-9223372036854777856.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<Half>(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper<long>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<long>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateSaturating<short>(0x0000)); @@ -749,6 +948,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +979,42 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateSaturating<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<float>(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(-9223373136366403584.0f)); + } + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +1025,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<float>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateSaturating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<float>(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(-9223373136366403584.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateSaturating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1080,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((long)0x7FFF_FFFF_FFFF_FFFF, NumberBaseHelper<long>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1131,63 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<decimal>(-1.0m)); + + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<double>(+0.0)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<double>(-0.0)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<double>(+1.0)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<double>(-1.0)); + + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateTruncating<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<double>(-9223372036854775808.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<double>(+9223372036854775808.0)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<double>(-9223372036854777856.0)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<Half>(Half.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((long)0x0000_0000_0000_FFE0, NumberBaseHelper<long>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<long>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateTruncating<short>(0x0000)); @@ -881,6 +1218,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0001), NumberBaseHelper<long>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1249,42 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<NFloat>(-1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((long)0x7FFF_FFFF_FFFF_FC00, NumberBaseHelper<long>.CreateTruncating<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<float>(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(-9223373136366403584.0f)); + } + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1295,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(+0.0f)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal((long)0x0000_0000_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((long)0x0000_0000_0000_0001, NumberBaseHelper<long>.CreateTruncating<float>(+1.0f)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((long)0x7FFF_FF80_0000_0000, NumberBaseHelper<long>.CreateTruncating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(-9223372036854775808.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<float>(+9223372036854775808.0f)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(-9223373136366403584.0f)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(unchecked((long)0x7FFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((long)0x8000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((long)0x0000000000000000, NumberBaseHelper<long>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1350,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0001), NumberBaseHelper<long>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((long)0x0000_0000_0000_0000), NumberBaseHelper<long>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((long)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<long>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1590,6 @@ namespace System.Tests Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), NumberBaseHelper<long>.MinMagnitudeNumber(unchecked((long)0xFFFFFFFFFFFFFFFF), 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<byte>(0x00, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<byte>(0x01, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((long)0x000000000000007F, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<byte>(0x80, out result)); - Assert.Equal((long)0x0000000000000080, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((long)0x00000000000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((long)0x0000000000008000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((long)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<short>(0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<short>(0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFF8000), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFF80000000), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(unchecked((long)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<long>(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<long>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((long)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<long>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFF80000000), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((long)0x000000000000007F, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFF80), result); - - Assert.True(NumberBaseHelper<long>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((long)0xFFFFFFFFFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((long)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((long)0x0000000000008000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((long)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((long)0x0000000080000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((long)0x00000000FFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - long result; - - Assert.True(NumberBaseHelper<long>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper<long>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<long>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((long)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - long result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((long)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((long)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((long)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((long)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((long)0x0000000080000000, result); - - Assert.True(NumberBaseHelper<long>.TryCreate<nuint>(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 6817debb45e..4af074c3d5c 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 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet16Test() + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper<nint>.CreateChecked<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<decimal>(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<decimal>(-1.0m)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<double>(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateChecked<double>(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<double>(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<double>(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateChecked<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateChecked<double>(-9223372036854775808.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(+9223372036854775808.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<double>(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateChecked<double>(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateChecked<double>(-2147483648.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(+2147483648.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(-2147483649.0)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<Half>(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper<nint>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<nint>.CreateChecked<Half>(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper<nint>.CreateChecked<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper<nint>.CreateChecked<Half>(Half.MinValue)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<Half>(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateChecked<short>(0x0000)); Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateChecked<short>(0x0001)); @@ -1104,7 +1195,7 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet32Test() + public static void CreateCheckedFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateChecked<int>(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateChecked<int>(0x00000001)); @@ -1114,7 +1205,7 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet64Test() + public static void CreateCheckedFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1135,7 +1226,25 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudetPtrTest() + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.MinValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<Int128>(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1156,6 +1265,46 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<NFloat>((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateChecked<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateChecked<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<NFloat>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateChecked<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateChecked<NFloat>(-2147483648.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(+2147483648.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(-2147483904.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateChecked<sbyte>(0x00)); @@ -1166,6 +1315,46 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<float>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateChecked<float>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<float>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<float>(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper<nint>.CreateChecked<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateChecked<float>(-9223372036854775808.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(+9223372036854775808.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateChecked<float>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateChecked<float>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateChecked<float>(-2147483648.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(+2147483648.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(-2147483904.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateChecked<ushort>(0x0000)); @@ -1218,6 +1407,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nint>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1259,7 +1458,96 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet16Test() + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper<nint>.CreateSaturating<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<decimal>(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<decimal>(-1.0m)); + } + + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<double>(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateSaturating<double>(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<double>(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<double>(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateSaturating<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateSaturating<double>(-9223372036854775808.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<double>(+9223372036854775808.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<double>(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<double>(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateSaturating<double>(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateSaturating<double>(-2147483648.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<double>(+2147483648.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<double>(-2147483649.0)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<nint>.CreateSaturating<Half>(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper<nint>.CreateSaturating<Half>(Half.MinValue)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<Half>(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateSaturating<short>(0x0000)); Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateSaturating<short>(0x0001)); @@ -1269,7 +1557,7 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet32Test() + public static void CreateSaturatingFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateSaturating<int>(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateSaturating<int>(0x00000001)); @@ -1279,7 +1567,7 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet64Test() + public static void CreateSaturatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1300,7 +1588,26 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudetPtrTest() + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.One)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.MinValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1321,6 +1628,45 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<NFloat>((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateSaturating<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateSaturating<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<NFloat>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateSaturating<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateSaturating<NFloat>(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateSaturating<sbyte>(0x00)); @@ -1331,6 +1677,45 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<float>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<float>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<float>(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper<nint>.CreateSaturating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateSaturating<float>(-9223372036854775808.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<float>(+9223372036854775808.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<float>(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateSaturating<float>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateSaturating<float>(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<float>(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<float>(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateSaturating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateSaturating<ushort>(0x0000)); @@ -1383,6 +1768,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1424,7 +1819,96 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet16Test() + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((nint)0x0000_0000_0000_0001, NumberBaseHelper<nint>.CreateTruncating<decimal>(+1.0m)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<decimal>(-1.0m)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<decimal>(-1.0m)); + } + + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<double>(+0.0)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateTruncating<double>(-0.0)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<double>(+1.0)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<double>(-1.0)); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateTruncating<double>(+9223372036854774784.0)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<double>(-9223372036854775808.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<double>(+9223372036854775808.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<double>(-9223372036854777856.0)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<double>(-1.0)); + + Assert.Equal((nint)0x7FFF_FFFF, NumberBaseHelper<nint>.CreateTruncating<double>(+2147483647.0)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateTruncating<double>(-2147483648.0)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<double>(+2147483648.0)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<double>(-2147483649.0)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_0000_0000_FFE0, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_0020), NumberBaseHelper<nint>.CreateTruncating<Half>(Half.MinValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((nint)0x0000_FFE0, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((nint)0xFFFF_0020), NumberBaseHelper<nint>.CreateTruncating<Half>(Half.MinValue)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<Half>(Half.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromInt16Test() { if (Environment.Is64BitProcess) { @@ -1445,7 +1929,7 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet32Test() + public static void CreateTruncatingFromInt32Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateTruncating<int>(0x00000000)); Assert.Equal((nint)0x00000001, NumberBaseHelper<nint>.CreateTruncating<int>(0x00000001)); @@ -1455,7 +1939,7 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet64Test() + public static void CreateTruncatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1476,7 +1960,27 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudetPtrTest() + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + } + + [Fact] + public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1497,6 +2001,45 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<NFloat>((NFloat)(-1.0))); + + Assert.Equal(unchecked((nint)0x7FFF_FFFF_FFFF_FC00), NumberBaseHelper<nint>.CreateTruncating<NFloat>((NFloat)(+9223372036854774784.0))); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<NFloat>((NFloat)(-9223372036854775808.0))); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>((NFloat)(+9223372036854775808.0))); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>((NFloat)(-9223372036854777856.0))); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<NFloat>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateTruncating<NFloat>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateTruncating<NFloat>(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { if (Environment.Is64BitProcess) @@ -1518,6 +2061,45 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<float>(+0.0f)); + Assert.Equal((nint)0x0000_0000_0000_0000, NumberBaseHelper<nint>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<float>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<float>(-1.0f)); + + Assert.Equal(unchecked((nint)0x7FFF_FF80_0000_0000), NumberBaseHelper<nint>.CreateTruncating<float>(+9223371487098961920.0f)); + Assert.Equal(unchecked((nint)0x8000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<float>(-9223372036854775808.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<float>(+9223372036854775808.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<float>(-9223373136366403584.0f)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((nint)0x7FFF_FF80, NumberBaseHelper<nint>.CreateTruncating<float>(+2147483520.0f)); + Assert.Equal(unchecked((nint)0x8000_0000), NumberBaseHelper<nint>.CreateTruncating<float>(-2147483648.0f)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<float>(+2147483648.0f)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<float>(-2147483904.0f)); + } + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(nint.MaxValue, NumberBaseHelper<nint>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(nint.MinValue, NumberBaseHelper<nint>.CreateTruncating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((nint)0x00000000, NumberBaseHelper<nint>.CreateTruncating<ushort>(0x0000)); @@ -1559,6 +2141,26 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((nint)0x0000_0000, NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((nint)0x0000_0001, NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128.One)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000_0000_0000), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF_FFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + else + { + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((nint)0x0000_0000), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((nint)0xFFFF_FFFF), NumberBaseHelper<nint>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -2020,337 +2622,6 @@ namespace System.Tests } } - [Fact] - public static void TryCreateFromByteTest() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<byte>(0x00, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<byte>(0x01, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((nint)0x0000007F, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<byte>(0x80, out result)); - Assert.Equal((nint)0x00000080, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((nint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((nint)0x00008000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((nint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet16Test() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<short>(0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<short>(0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFF8000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet32Test() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(unchecked((nint)(int)0x80000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<int>(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<nint>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(unchecked((nint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFroMinMagnitudetPtrTest() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked(unchecked((nint)0x80000000)), out result)); - Assert.Equal(unchecked((nint)0x80000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nint>(unchecked(unchecked((nint)0xFFFFFFFF)), out result)); - Assert.Equal(unchecked((nint)0xFFFFFFFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((nint)0x0000007F, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFF80), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((nint)(int)0xFFFFFFFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - nint result; - - Assert.True(NumberBaseHelper<nint>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((nint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((nint)0x00008000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((nint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(unchecked((nint)0x0000000080000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x00000000FFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nint>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(unchecked((nint)0x00000000000000001), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((nint)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper<nint>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - nint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((nint)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((nint)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((nint)0x00000001, result); - - Assert.True(NumberBaseHelper<nint>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((nint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<nuint>(unchecked(unchecked((nuint)0x80000000)), out result)); - Assert.Equal((nint)0x00000000, result); - - Assert.False(NumberBaseHelper<nint>.TryCreate<nuint>(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 b0be250fc68..3415a85dd79 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 @@ -587,6 +588,69 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<decimal>(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<decimal>(-1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<double>(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<double>(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<double>(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<double>(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<double>(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<double>(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateChecked<double>(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<double>(-128.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(+128.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(-129.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<Half>(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<Half>(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateChecked<Half>((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<Half>((Half)(-128.0f))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>((Half)(+128.0f))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>((Half)(-129.0f))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<short>(0x0000)); @@ -617,6 +681,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +712,31 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<NFloat>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateChecked<NFloat>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<NFloat>(-128.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(+128.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(-129.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<sbyte>(0x00)); @@ -648,6 +747,31 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<float>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<float>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<float>(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<float>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateChecked<float>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateChecked<float>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateChecked<float>(-128.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(+128.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(-129.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<ushort>(0x0000)); @@ -678,6 +802,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<sbyte>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +853,69 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<decimal>(-1.0m)); + + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<double>(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<double>(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<double>(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<double>(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<double>(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<double>(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<double>(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<double>(-128.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<double>(+128.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<double>(-129.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<Half>(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<Half>(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<Half>((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Half>((Half)(-128.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<Half>((Half)(+128.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Half>((Half)(-129.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<short>(0x0000)); @@ -749,6 +946,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +977,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +1012,31 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<float>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<float>(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<float>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateSaturating<float>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<float>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<float>(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<float>(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<float>(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateSaturating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1067,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1118,69 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<decimal>(-1.0m)); + + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<double>(+0.0)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<double>(-0.0)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<double>(+double.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<double>(-double.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateTruncating<double>(+1.0)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<double>(-1.0)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateTruncating<double>(+127.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<double>(-128.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<double>(+128.0)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<double>(-129.0)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<double>(double.NegativeInfinity)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<Half>(+Half.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<Half>(-Half.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateTruncating<Half>((Half)(+127.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<Half>((Half)(-128.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<Half>((Half)(+128.0f))); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<Half>((Half)(-129.0f))); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<Half>(Half.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<short>(0x0000)); @@ -881,6 +1211,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper<sbyte>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(unchecked((sbyte)0x01), NumberBaseHelper<sbyte>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper<sbyte>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1242,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1277,31 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<float>(+0.0f)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<float>(+float.Epsilon)); + Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((sbyte)0x01, NumberBaseHelper<sbyte>.CreateTruncating<float>(+1.0f)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<float>(-1.0f)); + + Assert.Equal((sbyte)0x7F, NumberBaseHelper<sbyte>.CreateTruncating<float>(+127.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<float>(-128.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<float>(+128.0f)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<float>(-129.0f)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(unchecked((sbyte)0x7F), NumberBaseHelper<sbyte>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(unchecked((sbyte)0x80), NumberBaseHelper<sbyte>.CreateTruncating<float>(float.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((sbyte)0x00, NumberBaseHelper<sbyte>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1332,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper<sbyte>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(unchecked((sbyte)0x01), NumberBaseHelper<sbyte>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(unchecked((sbyte)0x00), NumberBaseHelper<sbyte>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1572,6 @@ namespace System.Tests Assert.Equal(unchecked((sbyte)0xFF), NumberBaseHelper<sbyte>.MinMagnitudeNumber(unchecked((sbyte)0xFF), (sbyte)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<byte>(0x00, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<byte>(0x01, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((sbyte)0x7F, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<byte>(0x80, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<short>(0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<short>(0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - sbyte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - else - { - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((sbyte)0x7F, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(unchecked((sbyte)0x80), result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(unchecked((sbyte)0xFF), result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - sbyte result; - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - sbyte result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((sbyte)0x00, result); - } - else - { - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.True(NumberBaseHelper<sbyte>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((sbyte)0x01, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((sbyte)0x00, result); - - Assert.False(NumberBaseHelper<sbyte>.TryCreate<nuint>(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 4692ecfe55e..709bd3d0492 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) { @@ -1040,6 +1041,69 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateChecked<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateChecked<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateChecked<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateChecked<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<double>(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateChecked<double>(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<double>(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<double>(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateChecked<double>(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<double>(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<float>.CreateChecked<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<float>.CreateChecked<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<float>.CreateChecked<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<float>.CreateChecked<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<float>.CreateChecked<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<float>.CreateChecked<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<float>.CreateChecked<Half>(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateChecked<short>(0x0000)); @@ -1101,6 +1165,51 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateChecked<NFloat>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateChecked<NFloat>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateChecked<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateChecked<NFloat>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateChecked<NFloat>(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateChecked<sbyte>(0x00)); @@ -1111,6 +1220,32 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateChecked<float>(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateChecked<float>(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateChecked<float>(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateChecked<float>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateChecked<float>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateChecked<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateChecked<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateChecked<float>(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateChecked<float>(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateChecked<float>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateChecked<float>(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateChecked<float>(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateChecked<float>(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateChecked<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateChecked<ushort>(0x0000)); @@ -1196,6 +1331,69 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateSaturating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateSaturating<double>(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<double>(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<double>(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateSaturating<double>(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<double>(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<float>.CreateSaturating<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<float>.CreateSaturating<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<float>.CreateSaturating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<float>.CreateSaturating<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<float>.CreateSaturating<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<float>.CreateSaturating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateSaturating<short>(0x0000)); @@ -1257,6 +1455,51 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateSaturating<NFloat>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateSaturating<NFloat>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateSaturating<NFloat>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateSaturating<NFloat>(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateSaturating<sbyte>(0x00)); @@ -1267,6 +1510,32 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateSaturating<float>(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateSaturating<float>(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateSaturating<float>(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateSaturating<float>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateSaturating<float>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateSaturating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateSaturating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateSaturating<float>(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateSaturating<float>(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateSaturating<float>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateSaturating<float>(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateSaturating<float>(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateSaturating<float>(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateSaturating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateSaturating<ushort>(0x0000)); @@ -1352,6 +1621,69 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + AssertBitwiseEqual(-79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(decimal.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(-1.0m)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(-0.0m)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(+0.0m)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(+1.0m)); + AssertBitwiseEqual(+79228162514264337593543950335.0f, NumberBaseHelper<float>.CreateTruncating<decimal>(decimal.MaxValue)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<double>(double.NegativeInfinity)); + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<double>(double.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateTruncating<double>(-1.0)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<double>(-DoubleTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<double>(-DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<double>(-double.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<double>(-0.0)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<double>(+0.0)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<double>(double.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<double>(DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<double>(DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateTruncating<double>(1.0)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<double>(double.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<double>(double.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<Half>(Half.NegativeInfinity)); + + AssertBitwiseEqual(-65504.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.MinValue)); + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.NegativeOne)); + + AssertBitwiseEqual(-6.1035156E-05f, NumberBaseHelper<float>.CreateTruncating<Half>(-HalfTests_GenericMath.MinNormal)); + AssertBitwiseEqual(-6.097555E-05f, NumberBaseHelper<float>.CreateTruncating<Half>(-HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(-5.9604645E-08f, NumberBaseHelper<float>.CreateTruncating<Half>(-Half.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.NegativeZero)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.Zero)); + AssertBitwiseEqual(+5.9604645E-08f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.Epsilon)); + AssertBitwiseEqual(+6.097555E-05f, NumberBaseHelper<float>.CreateTruncating<Half>(HalfTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+6.1035156E-05f, NumberBaseHelper<float>.CreateTruncating<Half>(HalfTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.One)); + AssertBitwiseEqual(+65504.0f, NumberBaseHelper<float>.CreateTruncating<Half>(Half.MaxValue)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<Half>(Half.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateTruncating<short>(0x0000)); @@ -1413,6 +1745,51 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(-0.0f)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(+0.0f)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(-1.0f)); + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(+1.0f)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + + if (Environment.Is64BitProcess) + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>((NFloat)(-DoubleTests_GenericMath.MinNormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>((NFloat)(-DoubleTests_GenericMath.MaxSubnormal))); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>((NFloat)DoubleTests_GenericMath.MaxSubnormal)); + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<NFloat>((NFloat)DoubleTests_GenericMath.MinNormal)); + + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.MaxValue)); + } + else + { + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.MinValue)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateTruncating<NFloat>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateTruncating<NFloat>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateTruncating<NFloat>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateTruncating<NFloat>(MinNormal)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.MaxValue)); + } + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateTruncating<sbyte>(0x00)); @@ -1423,6 +1800,32 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + AssertBitwiseEqual(float.NegativeInfinity, NumberBaseHelper<float>.CreateTruncating<float>(float.NegativeInfinity)); + AssertBitwiseEqual(float.MinValue, NumberBaseHelper<float>.CreateTruncating<float>(float.MinValue)); + + AssertBitwiseEqual(-1.0f, NumberBaseHelper<float>.CreateTruncating<float>(-1.0f)); + + AssertBitwiseEqual(-MinNormal, NumberBaseHelper<float>.CreateTruncating<float>(-MinNormal)); + AssertBitwiseEqual(-MaxSubnormal, NumberBaseHelper<float>.CreateTruncating<float>(-MaxSubnormal)); + AssertBitwiseEqual(-float.Epsilon, NumberBaseHelper<float>.CreateTruncating<float>(-float.Epsilon)); + AssertBitwiseEqual(-0.0f, NumberBaseHelper<float>.CreateTruncating<float>(-0.0f)); + + AssertBitwiseEqual(+0.0f, NumberBaseHelper<float>.CreateTruncating<float>(+0.0f)); + AssertBitwiseEqual(+float.Epsilon, NumberBaseHelper<float>.CreateTruncating<float>(float.Epsilon)); + AssertBitwiseEqual(+MaxSubnormal, NumberBaseHelper<float>.CreateTruncating<float>(MaxSubnormal)); + AssertBitwiseEqual(+MinNormal, NumberBaseHelper<float>.CreateTruncating<float>(MinNormal)); + + AssertBitwiseEqual(+1.0f, NumberBaseHelper<float>.CreateTruncating<float>(1.0f)); + + AssertBitwiseEqual(float.MaxValue, NumberBaseHelper<float>.CreateTruncating<float>(float.MaxValue)); + AssertBitwiseEqual(float.PositiveInfinity, NumberBaseHelper<float>.CreateTruncating<float>(float.PositiveInfinity)); + + AssertBitwiseEqual(float.NaN, NumberBaseHelper<float>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { AssertBitwiseEqual(0.0f, NumberBaseHelper<float>.CreateTruncating<ushort>(0x0000)); @@ -1907,321 +2310,6 @@ namespace System.Tests AssertBitwiseEqual(1.0f, NumberBaseHelper<float>.MinMagnitudeNumber(float.PositiveInfinity, 1.0f)); } - [Fact] - public static void TryCreateFromByteTest() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<byte>(0x00, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<byte>(0x01, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(127.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<byte>(0x80, out result)); - Assert.Equal(128.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(255.0f, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(32768.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(65535.0f, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<short>(0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<short>(0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(-32768.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(-2147483648.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<long>(unchecked(unchecked((long)0x8000000000000000)), out result)); - Assert.Equal(-9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<long>(unchecked(unchecked((long)0xFFFFFFFFFFFFFFFF)), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromInt128Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<Int128>(new Int128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<Int128>(new Int128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<Int128>(new Int128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(-170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<Int128>(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<float>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(-9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - else - { - Assert.True(NumberBaseHelper<float>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(-2147483648.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(-1.0f, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(127.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(-128.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(-1.0f, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(32767.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(32768.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(65535.0f, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(2147483648.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(4294967295.0f, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(9223372036854775807.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(9223372036854775808.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(18446744073709551615.0f, result); - } - - [Fact] - public static void TryCreateFromUInt128Test() - { - float result; - - Assert.True(NumberBaseHelper<float>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<UInt128>(new UInt128(0x0000_0000_0000_0000, 0x0000_0000_0000_0001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<UInt128>(new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), out result)); - Assert.Equal(170141183460469231731687303715884105727.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<UInt128>(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), out result)); - Assert.Equal(170141183460469231731687303715884105728.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<UInt128>(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<float>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(9223372036854775807.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - // Assert.Equal(9223372036854775808.0f, result); - // - // Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - // Assert.Equal(18446744073709551615.0f, result); - } - else - { - Assert.True(NumberBaseHelper<float>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(0.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(1.0f, result); - - Assert.True(NumberBaseHelper<float>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(2147483647.0f, result); - - // https://github.com/dotnet/roslyn/issues/60714 - // Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - // Assert.Equal(2147483648.0f, result); - // - // Assert.True(NumberBaseHelper<float>.TryCreate<nuint>(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 c572abcf2a6..a6912f17c00 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 @@ -721,6 +722,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateChecked<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -742,6 +753,40 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<NFloat>(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateChecked<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<NFloat>((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateChecked<NFloat>(float.MaxValue)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(-1.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<UInt128>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<sbyte>(0x00)); @@ -802,6 +847,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateChecked<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateChecked<UInt128>(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<UInt128>.CreateChecked<UInt128>(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -928,6 +983,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -949,6 +1014,40 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<NFloat>((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(float.MaxValue)); + } + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(-1.0f)); + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<sbyte>(0x00)); @@ -1009,6 +1108,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<UInt128>(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<UInt128>.CreateSaturating<UInt128>(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1135,6 +1244,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<UInt128>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -1156,6 +1275,40 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(+0.0f)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(-0.0f)); + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(+1.0f)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<NFloat>((NFloat)(+170141183460469231731687303715884105728.0))); + Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<NFloat>((NFloat)(+340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>((NFloat)(+340282366920938463463374607431768211456.0))); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>((NFloat)(-340282366920938425684442744474606501888.0))); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(NFloat.MaxValue)); + } + else + { + Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(+170141183460469231731687303715884105728.0f)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(float.MaxValue)); + } + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(-1.0f)); + + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<sbyte>(0x00)); @@ -1216,6 +1369,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal(Zero, NumberBaseHelper<UInt128>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal(One, NumberBaseHelper<UInt128>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(Int128MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<UInt128>(Int128MaxValue)); + Assert.Equal(Int128MaxValuePlusOne, NumberBaseHelper<UInt128>.CreateTruncating<UInt128>(Int128MaxValuePlusOne)); + Assert.Equal(MaxValue, NumberBaseHelper<UInt128>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1446,421 +1609,6 @@ namespace System.Tests Assert.Equal(One, NumberBaseHelper<UInt128>.MinMagnitudeNumber(MaxValue, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<byte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<byte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<byte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<byte>(0x80, out result)); - Assert.Equal(SByteMaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<byte>(0xFF, out result)); - Assert.Equal(ByteMaxValue, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromDecimalTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<decimal>(decimal.Zero, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<decimal>(decimal.One, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<decimal>(decimal.MaxValue, out result)); - Assert.Equal(new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<decimal>(decimal.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<decimal>(decimal.MinusOne, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromDoubleTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(+0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(-0.0, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(+double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(+1.0, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(+170141183460469231731687303715884105728.0, out result)); - Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<double>(+340282366920938425684442744474606501888.0, out result)); - Assert.Equal(new UInt128(0xFFFF_FFFF_FFFF_F800, 0x0000_0000_0000_0000), result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(-double.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(-1.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(+340282366920938463463374607431768211456.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(-340282366920938425684442744474606501888.0, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(double.MaxValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(double.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(double.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<double>(double.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromHalfTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<Half>((Half)(+0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<Half>((Half)(-0.0), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<Half>(+Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<Half>((Half)(+1.0), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<Half>(Half.MaxValue, out result)); - Assert.Equal(+65504U, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<Half>(-Half.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<Half>((Half)(-1.0), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<Half>(Half.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<Half>(Half.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<Half>(Half.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<short>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<short>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<int>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<int>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - UInt128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - else - { - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal(Zero, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal(SByteMaxValue, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromSingleTest() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(+0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(-0.0f, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(+float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(+1.0f, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(+170141183460469231731687303715884105728.0f, out result)); - Assert.Equal(new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<float>(float.MaxValue, out result)); - Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<float>(-float.Epsilon, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<float>(-1.0f, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<float>(float.MinValue, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<float>(float.PositiveInfinity, out result)); - Assert.Equal(Zero, result); - - Assert.False(NumberBaseHelper<UInt128>.TryCreate<float>(float.NegativeInfinity, out result)); - Assert.Equal(Zero, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal(Int16MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal(Int16MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal(UInt16MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal(UInt32MaxValue, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - UInt128 result; - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(UInt64MaxValue, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - UInt128 result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(Int64MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(Int64MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(UInt64MaxValue, result); - } - else - { - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal(Zero, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal(One, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal(Int32MaxValue, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal(Int32MaxValuePlusOne, result); - - Assert.True(NumberBaseHelper<UInt128>.TryCreate<nuint>(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 1cb5e4388ea..9cf4fa0c6fa 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 @@ -587,6 +588,64 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<double>(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<double>(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<double>(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<double>(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateChecked<double>(+65535.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(+65536.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<Half>(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper<ushort>.CreateChecked<Half>(Half.MaxValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Half>(Half.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<short>(0x0000)); @@ -617,6 +676,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -638,6 +707,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateChecked<NFloat>(65535.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(+65536.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<sbyte>(0x00)); @@ -648,6 +741,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<float>(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<float>(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<float>(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateChecked<float>(+65535.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(+65536.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<ushort>(0x0000)); @@ -678,6 +795,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ushort>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -719,6 +846,64 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<double>(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<double>(+65535.0)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(-1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<double>(+65536.0)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.MaxValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<short>(0x0000)); @@ -749,6 +934,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -770,6 +965,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<sbyte>(0x00)); @@ -780,6 +999,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<float>(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<float>(+65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<float>(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<ushort>(0x0000)); @@ -810,6 +1053,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -851,6 +1104,64 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(+0.0)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(-0.0)); + + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(+double.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<double>(+1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<double>(+65535.0)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(-1.0)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<double>(+65536.0)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.One)); + Assert.Equal((ushort)0xFFE0, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.MaxValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.MinValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<short>(0x0000)); @@ -881,6 +1192,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -902,6 +1223,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<sbyte>(0x00)); @@ -912,6 +1257,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(+0.0f)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<float>(+1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<float>(+65535.0f)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(-1.0f)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<float>(+65536.0f)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<ushort>(0x0000)); @@ -942,6 +1311,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ushort)0x0000, NumberBaseHelper<ushort>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ushort)0xFFFF, NumberBaseHelper<ushort>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1172,277 +1551,6 @@ namespace System.Tests Assert.Equal((ushort)0x0001, NumberBaseHelper<ushort>.MinMagnitudeNumber((ushort)0xFFFF, (ushort)1)); } - [Fact] - public static void TryCreateFromByteTest() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<byte>(0x00, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<byte>(0x01, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((ushort)0x007F, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<byte>(0x80, out result)); - Assert.Equal((ushort)0x0080, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((ushort)0x00FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((ushort)0x8000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((ushort)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<short>(0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<short>(0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - ushort result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper<ushort>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((ushort)0x007F, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((ushort)0x7FFF, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((ushort)0x8000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((ushort)0xFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - ushort result; - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - ushort result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ushort)0x0000, result); - } - else - { - Assert.True(NumberBaseHelper<ushort>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.True(NumberBaseHelper<ushort>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((ushort)0x0001, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((ushort)0x0000, result); - - Assert.False(NumberBaseHelper<ushort>.TryCreate<nuint>(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 06ee6bd14d3..a2a44eac10a 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 @@ -588,6 +589,64 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<double>(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<double>(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<double>(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<double>(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateChecked<double>(+4294967295.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(+4294967296.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<Half>(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper<uint>.CreateChecked<Half>(Half.MaxValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Half>(Half.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<short>(0x0000)); @@ -618,6 +677,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -639,6 +708,41 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateChecked<NFloat>((NFloat)(4294967295.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateChecked<NFloat>(4294967040.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(+4294967296.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<sbyte>(0x00)); @@ -649,6 +753,30 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<float>(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<float>(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateChecked<float>(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateChecked<float>(+4294967040.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(+4294967296.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<ushort>(0x0000)); @@ -679,6 +807,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<uint>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -720,6 +858,64 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<double>(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<double>(+4294967295.0)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(-1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<double>(+4294967296.0)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.MaxValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateSaturating<short>(0x0000)); @@ -750,6 +946,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -771,6 +977,41 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<NFloat>((NFloat)(4294967295.0))); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<NFloat>(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateSaturating<NFloat>(4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<NFloat>(+4294967296.0f)); + } + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateSaturating<sbyte>(0x00)); @@ -781,6 +1022,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<float>(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateSaturating<float>(+4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<float>(+4294967296.0f)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateSaturating<ushort>(0x0000)); @@ -811,6 +1076,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -852,6 +1127,64 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(+0.0)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(-0.0)); + + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(+double.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<double>(+1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<double>(+4294967295.0)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(-1.0)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<double>(+4294967296.0)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.One)); + Assert.Equal((uint)0x0000_FFE0, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.MaxValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.MinValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateTruncating<short>(0x0000)); @@ -882,6 +1215,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -903,6 +1246,41 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<NFloat>((NFloat)(4294967295.0))); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<NFloat>(+4294967296.0f)); + } + else + { + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateTruncating<NFloat>(4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<NFloat>(+4294967296.0f)); + } + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateTruncating<sbyte>(0x00)); @@ -913,6 +1291,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(+0.0f)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<float>(+1.0f)); + Assert.Equal((uint)0xFFFF_FF00, NumberBaseHelper<uint>.CreateTruncating<float>(+4294967040.0f)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(-1.0f)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<float>(+4294967296.0f)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((uint)0x00000000, NumberBaseHelper<uint>.CreateTruncating<ushort>(0x0000)); @@ -943,6 +1345,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((uint)0x0000_0001, NumberBaseHelper<uint>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((uint)0x0000_0000, NumberBaseHelper<uint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((uint)0xFFFF_FFFF, NumberBaseHelper<uint>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1173,277 +1585,6 @@ namespace System.Tests Assert.Equal((uint)0x00000001, NumberBaseHelper<uint>.MinMagnitudeNumber((uint)0xFFFFFFFF, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<byte>(0x00, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<byte>(0x01, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((uint)0x0000007F, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<byte>(0x80, out result)); - Assert.Equal((uint)0x00000080, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((uint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((uint)0x00008000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((uint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<short>(0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<short>(0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - uint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper<uint>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((uint)0x0000007F, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((uint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((uint)0x00008000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((uint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((uint)0x80000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((uint)0xFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - uint result; - - Assert.True(NumberBaseHelper<uint>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((uint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - uint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.False(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((uint)0x00000000, result); - } - else - { - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((uint)0x00000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((uint)0x00000001, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((uint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((uint)0x80000000, result); - - Assert.True(NumberBaseHelper<uint>.TryCreate<nuint>(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 71a99821a98..6a30d6e12fe 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 @@ -586,6 +587,64 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<double>(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<double>(-0.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<double>(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<double>(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateChecked<double>(+18446744073709549568.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(+18446744073709551616.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<Half>(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper<ulong>.CreateChecked<Half>(Half.MaxValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Half>(Half.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] public static void CreateCheckedFromInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateChecked<short>(0x0000)); @@ -616,6 +675,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper<ulong>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -637,6 +706,42 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateChecked<NFloat>((NFloat)(18446744073709549568.0))); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateChecked<NFloat>(18446742974197923840.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(+18446744073709551616.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateChecked<sbyte>(0x00)); @@ -647,6 +752,31 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69795")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<float>(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<float>(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateChecked<float>(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateChecked<float>(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateChecked<float>(+18446742974197923840.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(+18446744073709551616.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateChecked<ushort>(0x0000)); @@ -677,6 +807,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper<ulong>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<ulong>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -718,6 +858,64 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(-0.0)); + + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<double>(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateSaturating<double>(+18446744073709549568.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(-1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<double>(+18446744073709551616.0)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.MaxValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] public static void CreateSaturatingFromInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateSaturating<short>(0x0000)); @@ -748,6 +946,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -769,6 +977,41 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateSaturating<NFloat>((NFloat)(18446744073709549568.0))); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(+18446744073709551616.0f)); + } + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateSaturating<sbyte>(0x00)); @@ -779,6 +1022,30 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<float>(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(+18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<float>(+18446744073709551616.0f)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateSaturating<ushort>(0x0000)); @@ -809,6 +1076,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -850,6 +1127,64 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(+0.0)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(-0.0)); + + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(+double.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<double>(+1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateTruncating<double>(+18446744073709549568.0)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(-1.0)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<double>(+18446744073709551616.0)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.One)); + Assert.Equal((ulong)0x0000_0000_0000_FFE0, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.MaxValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.MinValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] public static void CreateTruncatingFromInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateTruncating<short>(0x0000)); @@ -880,6 +1215,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) @@ -901,6 +1246,41 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_F800, NumberBaseHelper<ulong>.CreateTruncating<NFloat>((NFloat)(18446744073709549568.0))); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(+18446744073709551616.0f)); + } + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateTruncating<sbyte>(0x00)); @@ -911,6 +1291,30 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(+0.0f)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(-float.Epsilon)); + + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<float>(+1.0f)); + Assert.Equal((ulong)0xFFFF_FF00_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(+18446742974197923840.0f)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(-1.0f)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<float>(+18446744073709551616.0f)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((ulong)0x0000000000000000, NumberBaseHelper<ulong>.CreateTruncating<ushort>(0x0000)); @@ -941,6 +1345,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((ulong)0x0000_0000_0000_0001, NumberBaseHelper<ulong>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper<ulong>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper<ulong>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1171,277 +1585,6 @@ namespace System.Tests Assert.Equal((ulong)0x0000000000000001, NumberBaseHelper<ulong>.MinMagnitudeNumber((ulong)0xFFFFFFFFFFFFFFFF, 1)); } - [Fact] - public static void TryCreateFromByteTest() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<byte>(0x00, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<byte>(0x01, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((ulong)0x000000000000007F, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<byte>(0x80, out result)); - Assert.Equal((ulong)0x0000000000000080, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((ulong)0x00000000000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((ulong)0x0000000000008000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((ulong)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromInt16Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<short>(0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<short>(0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromInt32Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromInt64Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromIntPtrTest() - { - ulong result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - else - { - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((ulong)0x000000000000007F, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.False(NumberBaseHelper<ulong>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((ulong)0x0000000000007FFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((ulong)0x0000000000008000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((ulong)0x000000000000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((ulong)0x0000000080000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((ulong)0x00000000FFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - ulong result; - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((ulong)0x8000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - ulong result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0x7FFFFFFFFFFFFFFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal((ulong)0x8000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, result); - } - else - { - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((ulong)0x0000000000000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((ulong)0x0000000000000001, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((ulong)0x000000007FFFFFFF, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((ulong)0x0000000080000000, result); - - Assert.True(NumberBaseHelper<ulong>.TryCreate<nuint>(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 7cba3bc55eb..2318aefbd22 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 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet16Test() + public static void CreateCheckedFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateChecked<decimal>(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateChecked<decimal>(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper<nuint>.CreateChecked<decimal>(+1.0m)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<decimal>(decimal.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<decimal>(decimal.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<decimal>(decimal.MinusOne)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<double>(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<double>(-0.0)); + + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<double>(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<double>(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateChecked<double>(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateChecked<double>(+18446744073709549568.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<double>(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateChecked<double>(+4294967295.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(-1.0)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(+4294967296.0)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(double.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(double.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(double.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(double.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<double>(double.NaN)); + } + + [Fact] + public static void CreateCheckedFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<Half>(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<Half>(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<Half>(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<Half>(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<Half>(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper<nuint>.CreateChecked<Half>(Half.MaxValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Half>(Half.NegativeOne)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Half>(Half.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Half>(Half.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Half>(Half.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Half>(Half.NaN)); + } + + [Fact] + public static void CreateCheckedFromInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<short>(0x0000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateChecked<short>(0x0001)); @@ -1096,7 +1167,7 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet32Test() + public static void CreateCheckedFromInt32Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<int>(0x00000000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateChecked<int>(0x00000001)); @@ -1106,7 +1177,7 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudet64Test() + public static void CreateCheckedFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1127,7 +1198,17 @@ namespace System.Tests } [Fact] - public static void CreateCheckedFroMinMagnitudetPtrTest() + public static void CreateCheckedFromInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<Int128>(Int128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateChecked<Int128>(Int128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Int128>(Int128.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Int128>(Int128.MinValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<Int128>(Int128.NegativeOne)); + } + + [Fact] + public static void CreateCheckedFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1148,6 +1229,42 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<NFloat>(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<NFloat>(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateChecked<NFloat>(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateChecked<NFloat>((NFloat)18446744073709549568.0)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<NFloat>(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateChecked<NFloat>(4294967040.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(+4294967296.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateCheckedFromSByteTest() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<sbyte>(0x00)); @@ -1158,6 +1275,42 @@ namespace System.Tests } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/69794")] + public static void CreateCheckedFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<float>(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<float>(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<float>(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateChecked<float>(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateChecked<float>(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper<nuint>.CreateChecked<float>(+18446742974197923840.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateChecked<float>(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateChecked<float>(+4294967040.0f)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(-1.0f)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(+4294967296.0f)); + } + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(float.PositiveInfinity)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(float.NegativeInfinity)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(float.MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(float.MinValue)); + + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<float>(float.NaN)); + } + + [Fact] public static void CreateCheckedFromUInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<ushort>(0x0000)); @@ -1199,6 +1352,16 @@ namespace System.Tests } [Fact] + public static void CreateCheckedFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateChecked<UInt128>(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateChecked<UInt128>(UInt128.One)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Throws<OverflowException>(() => NumberBaseHelper<nuint>.CreateChecked<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateCheckedFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1240,7 +1403,75 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet16Test() + public static void CreateSaturatingFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateSaturating<decimal>(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateSaturating<decimal>(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper<nuint>.CreateSaturating<decimal>(+1.0m)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<decimal>(decimal.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<decimal>(decimal.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateSaturatingFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<double>(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<double>(-0.0)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<double>(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<double>(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateSaturating<double>(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateSaturating<double>(+18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<double>(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<double>(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<double>(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateSaturating<double>(+4294967295.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<double>(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<double>(+4294967296.0)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<double>(double.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<double>(double.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<double>(double.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<double>(double.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<double>(double.NaN)); + } + + [Fact] + public static void CreateSaturatingFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Half>(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Half>(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.MaxValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.NegativeOne)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.NegativeInfinity)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Half>(Half.NaN)); + } + + [Fact] + public static void CreateSaturatingFromInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateSaturating<short>(0x0000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateSaturating<short>(0x0001)); @@ -1250,7 +1481,7 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet32Test() + public static void CreateSaturatingFromInt32Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateSaturating<int>(0x00000000)); Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateSaturating<int>(0x00000001)); @@ -1260,7 +1491,7 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudet64Test() + public static void CreateSaturatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1281,7 +1512,17 @@ namespace System.Tests } [Fact] - public static void CreateSaturatingFroMinMagnitudetPtrTest() + public static void CreateSaturatingFromInt128Test() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<Int128>(Int128.Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<Int128>(Int128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<Int128>(Int128.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Int128>(Int128.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<Int128>(Int128.NegativeOne)); + } + + [Fact] + public static void CreateSaturatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1302,6 +1543,41 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateSaturating<NFloat>((NFloat)18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateSaturatingFromSByteTest() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateSaturating<sbyte>(0x00)); @@ -1312,6 +1588,41 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<float>(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<float>(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<float>(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateSaturating<float>(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateSaturating<float>(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper<nuint>.CreateSaturating<float>(+18446742974197923840.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<float>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<float>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateSaturating<float>(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateSaturating<float>(+4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<float>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<float>(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<float>(float.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<float>(float.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<float>(float.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<float>(float.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateSaturating<float>(float.NaN)); + } + + [Fact] public static void CreateSaturatingFromUInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateSaturating<ushort>(0x0000)); @@ -1353,6 +1664,16 @@ namespace System.Tests } [Fact] + public static void CreateSaturatingFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateSaturating<UInt128>(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateSaturating<UInt128>(UInt128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateSaturating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateSaturatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -1394,7 +1715,75 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet16Test() + public static void CreateTruncatingFromDecimalTest() + { + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateTruncating<decimal>(-0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0000, NumberBaseHelper<nuint>.CreateTruncating<decimal>(+0.0m)); + Assert.Equal((nuint)0x0000_0000_0000_0001, NumberBaseHelper<nuint>.CreateTruncating<decimal>(+1.0m)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<decimal>(decimal.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<decimal>(decimal.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<decimal>(decimal.MinusOne)); + } + + [Fact] + public static void CreateTruncatingFromDoubleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<double>(+0.0)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<double>(-0.0)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<double>(-double.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<double>(+double.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateTruncating<double>(+1.0)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateTruncating<double>(+18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<double>(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<double>(+18446744073709551616.0)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateTruncating<double>(+1.0)); + Assert.Equal((nuint)0xFFFF_FFFF, NumberBaseHelper<nuint>.CreateTruncating<double>(+4294967295.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<double>(-1.0)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<double>(+4294967296.0)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<double>(double.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<double>(double.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<double>(double.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<double>(double.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<double>(double.NaN)); + } + + [Fact] + public static void CreateTruncatingFromHalfTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.Zero)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<Half>(-Half.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<Half>(+Half.Epsilon)); + + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.One)); + Assert.Equal((nuint)0x0000_FFE0, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.MaxValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.NegativeOne)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.NegativeInfinity)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.MinValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<Half>(Half.NaN)); + } + + [Fact] + public static void CreateTruncatingFromInt16Test() { if (Environment.Is64BitProcess) { @@ -1415,7 +1804,7 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet32Test() + public static void CreateTruncatingFromInt32Test() { if (Environment.Is64BitProcess) { @@ -1436,7 +1825,7 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudet64Test() + public static void CreateTruncatingFromInt64Test() { if (Environment.Is64BitProcess) { @@ -1457,7 +1846,17 @@ namespace System.Tests } [Fact] - public static void CreateTruncatingFroMinMagnitudetPtrTest() + public static void CreateTruncatingFromInt128Test() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<Int128>(Int128.Zero)); + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateTruncating<Int128>(Int128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<Int128>(Int128.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<Int128>(Int128.MinValue)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<Int128>(Int128.NegativeOne)); + } + + [Fact] + public static void CreateTruncatingFromIntPtrTest() { if (Environment.Is64BitProcess) { @@ -1478,6 +1877,41 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromNFloatTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.NegativeZero)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(-NFloat.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(+NFloat.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FFFF_FFFF_F800), NumberBaseHelper<nuint>.CreateTruncating<NFloat>((NFloat)18446744073709549568.0)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<NFloat>(NFloat.NaN)); + } + + [Fact] public static void CreateTruncatingFromSByteTest() { if (Environment.Is64BitProcess) @@ -1499,6 +1933,41 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromSingleTest() + { + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<float>(+0.0f)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<float>(-0.0f)); + + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<float>(-float.Epsilon)); + Assert.Equal((nuint)0x0000_0000, NumberBaseHelper<nuint>.CreateTruncating<float>(-float.Epsilon)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(unchecked((nuint)0x0000_0000_0000_0001), NumberBaseHelper<nuint>.CreateTruncating<float>(+1.0f)); + Assert.Equal(unchecked((nuint)0xFFFF_FF00_0000_0000), NumberBaseHelper<nuint>.CreateTruncating<float>(+18446742974197923840.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<float>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<float>(+18446744073709551616.0f)); + } + else + { + Assert.Equal((nuint)0x0000_0001, NumberBaseHelper<nuint>.CreateTruncating<float>(+1.0f)); + Assert.Equal((nuint)0xFFFF_FF00, NumberBaseHelper<nuint>.CreateTruncating<float>(+4294967040.0f)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<float>(-1.0f)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<float>(+4294967296.0f)); + } + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<float>(float.PositiveInfinity)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<float>(float.NegativeInfinity)); + + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<float>(float.MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<float>(float.MinValue)); + + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<float>(float.NaN)); + } + + [Fact] public static void CreateTruncatingFromUInt16Test() { Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateTruncating<ushort>(0x0000)); @@ -1540,6 +2009,16 @@ namespace System.Tests } [Fact] + public static void CreateTruncatingFromUInt128Test() + { + Assert.Equal((nuint)0x00000000, NumberBaseHelper<nuint>.CreateTruncating<UInt128>(UInt128.Zero)); + Assert.Equal((nuint)0x00000001, NumberBaseHelper<nuint>.CreateTruncating<UInt128>(UInt128.One)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValue)); + Assert.Equal(nuint.MinValue, NumberBaseHelper<nuint>.CreateTruncating<UInt128>(UInt128Tests_GenericMath.Int128MaxValuePlusOne)); + Assert.Equal(nuint.MaxValue, NumberBaseHelper<nuint>.CreateTruncating<UInt128>(UInt128.MaxValue)); + } + + [Fact] public static void CreateTruncatingFromUIntPtrTest() { if (Environment.Is64BitProcess) @@ -2001,317 +2480,6 @@ namespace System.Tests } } - [Fact] - public static void TryCreateFromByteTest() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<byte>(0x00, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<byte>(0x01, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<byte>(0x7F, out result)); - Assert.Equal((nuint)0x0000007F, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<byte>(0x80, out result)); - Assert.Equal((nuint)0x00000080, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<byte>(0xFF, out result)); - Assert.Equal((nuint)0x000000FF, result); - } - - [Fact] - public static void TryCreateFromCharTest() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<char>((char)0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<char>((char)0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<char>((char)0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<char>((char)0x8000, out result)); - Assert.Equal((nuint)0x00008000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<char>((char)0xFFFF, out result)); - Assert.Equal((nuint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet16Test() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<short>(0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<short>(0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<short>(0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<short>(unchecked((short)0x8000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<short>(unchecked((short)0xFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet32Test() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<int>(0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<int>(0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<int>(0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<int>(unchecked((int)0x80000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<int>(unchecked((int)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFroMinMagnitudet64Test() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - } - else - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<long>(0x0000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<long>(0x0000000000000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<long>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<long>(unchecked((long)0x8000000000000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<long>(unchecked((long)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFroMinMagnitudetPtrTest() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - } - else - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>((nint)0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>((nint)0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nint>((nint)0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0x80000000), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<nint>(unchecked((nint)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromSByteTest() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<sbyte>(0x00, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<sbyte>(0x01, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<sbyte>(0x7F, out result)); - Assert.Equal((nuint)0x0000007F, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<sbyte>(unchecked((sbyte)0x80), out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<sbyte>(unchecked((sbyte)0xFF), out result)); - Assert.Equal((nuint)0x00000000, result); - } - - [Fact] - public static void TryCreateFromUInt16Test() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ushort>(0x0000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ushort>(0x0001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ushort>(0x7FFF, out result)); - Assert.Equal((nuint)0x00007FFF, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ushort>(0x8000, out result)); - Assert.Equal((nuint)0x00008000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ushort>(0xFFFF, out result)); - Assert.Equal((nuint)0x0000FFFF, result); - } - - [Fact] - public static void TryCreateFromUInt32Test() - { - nuint result; - - Assert.True(NumberBaseHelper<nuint>.TryCreate<uint>(0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<uint>(0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<uint>(0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<uint>(0x80000000, out result)); - Assert.Equal((nuint)0x80000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<uint>(0xFFFFFFFF, out result)); - Assert.Equal((nuint)0xFFFFFFFF, result); - } - - [Fact] - public static void TryCreateFromUInt64Test() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal(unchecked((nuint)0x00000000000000001), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal(unchecked((nuint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x0000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<ulong>(0x0000000000000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<ulong>(0x7FFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<ulong>(0x8000000000000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.False(NumberBaseHelper<nuint>.TryCreate<ulong>(0xFFFFFFFFFFFFFFFF, out result)); - Assert.Equal((nuint)0x00000000, result); - } - } - - [Fact] - public static void TryCreateFromUIntPtrTest() - { - nuint result; - - if (Environment.Is64BitProcess) - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0x0000000000000001), out result)); - Assert.Equal(unchecked((nuint)0x0000000000000001), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0x7FFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0x7FFFFFFFFFFFFFFF), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0x8000000000000000), out result)); - Assert.Equal(unchecked((nuint)0x8000000000000000), result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFFFFFFFFFF), out result)); - Assert.Equal(unchecked((nuint)0xFFFFFFFFFFFFFFFF), result); - } - else - { - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>((nuint)0x00000000, out result)); - Assert.Equal((nuint)0x00000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>((nuint)0x00000001, out result)); - Assert.Equal((nuint)0x00000001, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>((nuint)0x7FFFFFFF, out result)); - Assert.Equal((nuint)0x7FFFFFFF, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0x80000000), out result)); - Assert.Equal((nuint)0x80000000, result); - - Assert.True(NumberBaseHelper<nuint>.TryCreate<nuint>(unchecked((nuint)0xFFFFFFFF), out result)); - Assert.Equal((nuint)0xFFFFFFFF, result); - } - } - // // IShiftOperators // |