// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.Versioning; #pragma warning disable SA1121 // We use our own aliases since they differ per platform #if TARGET_32BIT using NativeExponentType = System.SByte; using NativeSignificandType = System.UInt32; using NativeType = System.Single; #else using NativeExponentType = System.Int16; using NativeSignificandType = System.UInt64; using NativeType = System.Double; #endif namespace System.Runtime.InteropServices { /// <summary>Defines an immutable value type that represents a floating type that has the same size as the native integer size.</summary> /// <remarks>It is meant to be used as an exchange type at the managed/unmanaged boundary to accurately represent in managed code unmanaged APIs that use a type alias for C or C++'s <c>float</c> on 32-bit platforms or <c>double</c> on 64-bit platforms, such as the CGFloat type in libraries provided by Apple.</remarks> [Intrinsic] [NonVersionable] // This only applies to field layout public readonly struct NFloat : IBinaryFloatingPointIeee754<NFloat>, IMinMaxValue<NFloat>, IUtf8SpanFormattable { private const NumberStyles DefaultNumberStyles = NumberStyles.Float | NumberStyles.AllowThousands; private readonly NativeType _value; /// <summary>Constructs an instance from a 32-bit floating point value.</summary> /// <param name="value">The floating-point value.</param> [NonVersionable] public NFloat(float value) { _value = value; } /// <summary>Constructs an instance from a 64-bit floating point value.</summary> /// <param name="value">The floating-point value.</param> [NonVersionable] public NFloat(double value) { _value = (NativeType)value; } /// <summary>Represents the smallest positive NFloat value that is greater than zero.</summary> public static NFloat Epsilon { [NonVersionable] get => new NFloat(NativeType.Epsilon); } /// <summary>Represents the largest finite value of a NFloat.</summary> public static NFloat MaxValue { [NonVersionable] get => new NFloat(NativeType.MaxValue); } /// <summary>Represents the smallest finite value of a NFloat.</summary> public static NFloat MinValue { [NonVersionable] get => new NFloat(NativeType.MinValue); } /// <summary>Represents a value that is not a number (NaN).</summary> public static NFloat NaN { [NonVersionable] get => new NFloat(NativeType.NaN); } /// <summary>Represents negative infinity.</summary> public static NFloat NegativeInfinity { [NonVersionable] get => new NFloat(NativeType.NegativeInfinity); } /// <summary>Represents positive infinity.</summary> public static NFloat PositiveInfinity { [NonVersionable] get => new NFloat(NativeType.PositiveInfinity); } /// <summary>Gets the size, in bytes, of an NFloat.</summary> public static int Size { [NonVersionable] get => sizeof(NativeType); } /// <summary>The underlying floating-point value of this instance.</summary> public double Value { [NonVersionable] get => _value; } // // Unary Arithmetic // /// <summary>Computes the unary plus of a value.</summary> /// <param name="value">The value for which to compute its unary plus.</param> /// <returns>The unary plus of <paramref name="value" />.</returns> [NonVersionable] public static NFloat operator +(NFloat value) => value; /// <summary>Computes the unary negation of a value.</summary> /// <param name="value">The value for which to compute its unary negation.</param> /// <returns>The unary negation of <paramref name="value" />.</returns> [NonVersionable] public static NFloat operator -(NFloat value) => new NFloat(-value._value); /// <summary>Increments a value.</summary> /// <param name="value">The value to increment.</param> /// <returns>The result of incrementing <paramref name="value" />.</returns> [NonVersionable] public static NFloat operator ++(NFloat value) { NativeType tmp = value._value; ++tmp; return new NFloat(tmp); } /// <summary>Decrements a value.</summary> /// <param name="value">The value to decrement.</param> /// <returns>The result of decrementing <paramref name="value" />.</returns> [NonVersionable] public static NFloat operator --(NFloat value) { NativeType tmp = value._value; --tmp; return new NFloat(tmp); } // // Binary Arithmetic // /// <summary>Adds two values together to compute their sum.</summary> /// <param name="left">The value to which <paramref name="right" /> is added.</param> /// <param name="right">The value which is added to <paramref name="left" />.</param> /// <returns>The sum of <paramref name="left" /> and <paramref name="right" />.</returns> [NonVersionable] public static NFloat operator +(NFloat left, NFloat right) => new NFloat(left._value + right._value); /// <summary>Subtracts two values to compute their difference.</summary> /// <param name="left">The value from which <paramref name="right" /> is subtracted.</param> /// <param name="right">The value which is subtracted from <paramref name="left" />.</param> /// <returns>The difference of <paramref name="right" /> subtracted from <paramref name="left" />.</returns> [NonVersionable] public static NFloat operator -(NFloat left, NFloat right) => new NFloat(left._value - right._value); /// <summary>Multiplies two values together to compute their product.</summary> /// <param name="left">The value which <paramref name="right" /> multiplies.</param> /// <param name="right">The value which multiplies <paramref name="left" />.</param> /// <returns>The product of <paramref name="left" /> multiplied-by <paramref name="right" />.</returns> [NonVersionable] public static NFloat operator *(NFloat left, NFloat right) => new NFloat(left._value * right._value); /// <summary>Divides two values together to compute their quotient.</summary> /// <param name="left">The value which <paramref name="right" /> divides.</param> /// <param name="right">The value which divides <paramref name="left" />.</param> /// <returns>The quotient of <paramref name="left" /> divided-by <paramref name="right" />.</returns> [NonVersionable] public static NFloat operator /(NFloat left, NFloat right) => new NFloat(left._value / right._value); /// <summary>Divides two values together to compute their remainder.</summary> /// <param name="left">The value which <paramref name="right" /> divides.</param> /// <param name="right">The value which divides <paramref name="left" />.</param> /// <returns>The remainder of <paramref name="left" /> divided-by <paramref name="right" />.</returns> [NonVersionable] public static NFloat operator %(NFloat left, NFloat right) => new NFloat(left._value % right._value); // // Comparisons // /// <summary>Compares two values to determine equality.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is equal to <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator ==(NFloat left, NFloat right) => left._value == right._value; /// <summary>Compares two values to determine inequality.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is not equal to <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator !=(NFloat left, NFloat right) => left._value != right._value; /// <summary>Compares two values to determine which is less.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is less than <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator <(NFloat left, NFloat right) => left._value < right._value; /// <summary>Compares two values to determine which is less or equal.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is less than or equal to <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator <=(NFloat left, NFloat right) => left._value <= right._value; /// <summary>Compares two values to determine which is greater.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is greater than <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator >(NFloat left, NFloat right) => left._value > right._value; /// <summary>Compares two values to determine which is greater or equal.</summary> /// <param name="left">The value to compare with <paramref name="right" />.</param> /// <param name="right">The value to compare with <paramref name="left" />.</param> /// <returns><c>true</c> if <paramref name="left" /> is greater than or equal to <paramref name="right" />; otherwise, <c>false</c>.</returns> [NonVersionable] public static bool operator >=(NFloat left, NFloat right) => left._value >= right._value; // // Explicit Convert To NFloat // /// <summary>Explicitly converts a <see cref="decimal" /> 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 explicit operator NFloat(decimal value) => new NFloat((NativeType)value); /// <summary>Explicitly converts a <see cref="double" /> 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 explicit operator NFloat(double value) => new NFloat((NativeType)value); // // Explicit Convert From NFloat // /// <summary>Explicitly converts a native-sized 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> [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="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> [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> [NonVersionable] [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> [NonVersionable] public static explicit operator float(NFloat value) => (float)(value._value); /// <summary>Explicitly converts a native-sized 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> [NonVersionable] [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> [NonVersionable] [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> [NonVersionable] [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="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> [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 // /// <summary>Implicitly converts a <see cref="byte" /> 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(byte value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="char" /> 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(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> [NonVersionable] public static implicit operator NFloat(short value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="int" /> 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(int value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="long" /> 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(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> [NonVersionable] public static implicit operator NFloat(nint value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="sbyte" /> 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] [CLSCompliant(false)] public static implicit operator NFloat(sbyte value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="float" /> 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(float value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="ushort" /> 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] [CLSCompliant(false)] public static implicit operator NFloat(ushort value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="uint" /> 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] [CLSCompliant(false)] public static implicit operator NFloat(uint value) => new NFloat((NativeType)value); /// <summary>Implicitly converts a <see cref="ulong" /> 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] [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> [NonVersionable] [CLSCompliant(false)] public static implicit operator NFloat(nuint value) => new NFloat((NativeType)value); // // Implicit Convert From NFloat // /// <summary>Implicitly converts a native-sized 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 implicit operator double(NFloat value) => (double)(value._value); /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is finite (zero, subnormal or normal); <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsFinite(NFloat value) => NativeType.IsFinite(value._value); /// <summary>Determines whether the specified value is infinite (positive or negative infinity).</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is infinite (positive or negative infinity); <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsInfinity(NFloat value) => NativeType.IsInfinity(value._value); /// <summary>Determines whether the specified value is NaN (not a number).</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is NaN (not a number); <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsNaN(NFloat value) => NativeType.IsNaN(value._value); /// <summary>Determines whether the specified value is negative.</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is negative; <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsNegative(NFloat value) => NativeType.IsNegative(value._value); /// <summary>Determines whether the specified value is negative infinity.</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is negative infinity; <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsNegativeInfinity(NFloat value) => NativeType.IsNegativeInfinity(value._value); /// <summary>Determines whether the specified value is normal.</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is normal; <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsNormal(NFloat value) => NativeType.IsNormal(value._value); /// <summary>Determines whether the specified value is positive infinity.</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is positive infinity; <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsPositiveInfinity(NFloat value) => NativeType.IsPositiveInfinity(value._value); /// <summary>Determines whether the specified value is subnormal.</summary> /// <param name="value">The floating-point value.</param> /// <returns><c>true</c> if the value is subnormal; <c>false</c> otherwise.</returns> [NonVersionable] public static bool IsSubnormal(NFloat value) => NativeType.IsSubnormal(value._value); /// <summary>Converts the string representation of a number to its floating-point number equivalent.</summary> /// <param name="s">A string that contains the number to convert.</param> /// <returns>A floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s" />.</returns> /// <exception cref="ArgumentNullException"><paramref name="s" /> is <c>null</c>.</exception> /// <exception cref="FormatException"><paramref name="s" /> does not represent a number in a valid format.</exception> public static NFloat Parse(string s) { var result = NativeType.Parse(s); return new NFloat(result); } /// <summary>Converts the string representation of a number in a specified style to its floating-point number equivalent.</summary> /// <param name="s">A string that contains the number to convert.</param> /// <param name="style">A bitwise combination of enumeration values that indicate the style elements that can be present in <paramref name="s" />.</param> /// <returns>A floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s" />.</returns> /// <exception cref="ArgumentException"> /// <para><paramref name="style" /> is not a <see cref="NumberStyles" /> value.</para> /// <para>-or-</para> /// <para><paramref name="style" /> includes the <see cref="NumberStyles.AllowHexSpecifier" /> or <see cref="NumberStyles.AllowBinarySpecifier" /> value.</para> /// </exception> /// <exception cref="ArgumentNullException"><paramref name="s" /> is <c>null</c>.</exception> /// <exception cref="FormatException"><paramref name="s" /> does not represent a number in a valid format.</exception> public static NFloat Parse(string s, NumberStyles style) { var result = NativeType.Parse(s, style); return new NFloat(result); } /// <summary>Converts the string representation of a number in a specified culture-specific format to its floating-point number equivalent.</summary> /// <param name="s">A string that contains the number to convert.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="s" />.</param> /// <returns>A floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s" />.</returns> /// <exception cref="ArgumentNullException"><paramref name="s" /> is <c>null</c>.</exception> /// <exception cref="FormatException"><paramref name="s" /> does not represent a number in a valid format.</exception> public static NFloat Parse(string s, IFormatProvider? provider) { var result = NativeType.Parse(s, provider); return new NFloat(result); } /// <summary>Converts the string representation of a number in a specified style and culture-specific format to its floating-point number equivalent.</summary> /// <param name="s">A string that contains the number to convert.</param> /// <param name="style">A bitwise combination of enumeration values that indicate the style elements that can be present in <paramref name="s" />.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="s" />.</param> /// <returns>A floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s" />.</returns> /// <exception cref="ArgumentException"> /// <para><paramref name="style" /> is not a <see cref="NumberStyles" /> value.</para> /// <para>-or-</para> /// <para><paramref name="style" /> includes the <see cref="NumberStyles.AllowHexSpecifier" /> or <see cref="NumberStyles.AllowBinarySpecifier" /> value.</para> /// </exception> /// <exception cref="ArgumentNullException"><paramref name="s" /> is <c>null</c>.</exception> /// <exception cref="FormatException"><paramref name="s" /> does not represent a number in a valid format.</exception> public static NFloat Parse(string s, NumberStyles style, IFormatProvider? provider) { var result = NativeType.Parse(s, style, provider); return new NFloat(result); } /// <summary>Converts a character span that contains the string representation of a number in a specified style and culture-specific format to its floating-point number equivalent.</summary> /// <param name="s">A character span that contains the number to convert.</param> /// <param name="style">A bitwise combination of enumeration values that indicate the style elements that can be present in <paramref name="s" />.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="s" />.</param> /// <returns>A floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s" />.</returns> /// <exception cref="ArgumentException"> /// <para><paramref name="style" /> is not a <see cref="NumberStyles" /> value.</para> /// <para>-or-</para> /// <para><paramref name="style" /> includes the <see cref="NumberStyles.AllowHexSpecifier" /> or <see cref="NumberStyles.AllowBinarySpecifier" /> value.</para> /// </exception> /// <exception cref="FormatException"><paramref name="s" /> does not represent a number in a valid format.</exception> public static NFloat Parse(ReadOnlySpan<char> s, NumberStyles style = DefaultNumberStyles, IFormatProvider? provider = null) { var result = NativeType.Parse(s, style, provider); return new NFloat(result); } /// <summary>Tries to convert the string representation of a number to its floating-point number equivalent.</summary> /// <param name="s">A read-only character span that contains the number to convert.</param> /// <param name="result">When this method returns, contains a floating-point number equivalent of the numeric value or symbol contained in <paramref name="s" /> if the conversion succeeded or zero if the conversion failed. The conversion fails if the <paramref name="s" /> is <c>null</c>, <see cref="string.Empty" />, or is not in a valid format. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param> /// <returns><c>true</c> if <paramref name="s" /> was converted successfully; otherwise, false.</returns> public static bool TryParse([NotNullWhen(true)] string? s, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(s, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <summary>Tries to convert a character span containing the string representation of a number to its floating-point number equivalent.</summary> /// <param name="s">A read-only character span that contains the number to convert.</param> /// <param name="result">When this method returns, contains a floating-point number equivalent of the numeric value or symbol contained in <paramref name="s" /> if the conversion succeeded or zero if the conversion failed. The conversion fails if the <paramref name="s" /> is <see cref="ReadOnlySpan{T}.Empty" /> or is not in a valid format. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param> /// <returns><c>true</c> if <paramref name="s" /> was converted successfully; otherwise, false.</returns> public static bool TryParse(ReadOnlySpan<char> s, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(s, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <summary>Tries to convert a UTF-8 character span containing the string representation of a number to its floating-point number equivalent.</summary> /// <param name="utf8Text">A read-only UTF-8 character span that contains the number to convert.</param> /// <param name="result">When this method returns, contains a floating-point number equivalent of the numeric value or symbol contained in <paramref name="utf8Text" /> if the conversion succeeded or zero if the conversion failed. The conversion fails if the <paramref name="utf8Text" /> is <see cref="ReadOnlySpan{T}.Empty" /> or is not in a valid format. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param> /// <returns><c>true</c> if <paramref name="utf8Text" /> was converted successfully; otherwise, false.</returns> public static bool TryParse(ReadOnlySpan<byte> utf8Text, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(utf8Text, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <summary>Tries to convert the string representation of a number in a specified style and culture-specific format to its floating-point number equivalent.</summary> /// <param name="s">A read-only character span that contains the number to convert.</param> /// <param name="style">A bitwise combination of enumeration values that indicate the style elements that can be present in <paramref name="s" />.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="s" />.</param> /// <param name="result">When this method returns, contains a floating-point number equivalent of the numeric value or symbol contained in <paramref name="s" /> if the conversion succeeded or zero if the conversion failed. The conversion fails if the <paramref name="s" /> is <c>null</c>, <see cref="string.Empty" />, or is not in a format compliant with <paramref name="style" />, or if <paramref name="style" /> is not a valid combination of <see cref="NumberStyles" /> enumeration constants. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param> /// <returns><c>true</c> if <paramref name="s" /> was converted successfully; otherwise, false.</returns> /// <exception cref="ArgumentException"> /// <para><paramref name="style" /> is not a <see cref="NumberStyles" /> value.</para> /// <para>-or-</para> /// <para><paramref name="style" /> includes the <see cref="NumberStyles.AllowHexSpecifier" /> or <see cref="NumberStyles.AllowBinarySpecifier" /> value.</para> /// </exception> public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(s, style, provider, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <summary>Tries to convert a character span containing the string representation of a number in a specified style and culture-specific format to its floating-point number equivalent.</summary> /// <param name="s">A read-only character span that contains the number to convert.</param> /// <param name="style">A bitwise combination of enumeration values that indicate the style elements that can be present in <paramref name="s" />.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="s" />.</param> /// <param name="result">When this method returns, contains a floating-point number equivalent of the numeric value or symbol contained in <paramref name="s" /> if the conversion succeeded or zero if the conversion failed. The conversion fails if the <paramref name="s" /> is <see cref="string.Empty" /> or is not in a format compliant with <paramref name="style" />, or if <paramref name="style" /> is not a valid combination of <see cref="NumberStyles" /> enumeration constants. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param> /// <returns><c>true</c> if <paramref name="s" /> was converted successfully; otherwise, false.</returns> /// <exception cref="ArgumentException"> /// <para><paramref name="style" /> is not a <see cref="NumberStyles" /> value.</para> /// <para>-or-</para> /// <para><paramref name="style" /> includes the <see cref="NumberStyles.AllowHexSpecifier" /> or <see cref="NumberStyles.AllowBinarySpecifier" /> value.</para> /// </exception> public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(s, style, provider, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <summary>Compares this instance to a specified object and returns an integer that indicates whether the value of this instance is less than, equal to, or greater than the value of the specified object.</summary> /// <param name="obj">An object to compare, or <c>null</c>.</param> /// <returns> /// <para>A signed number indicating the relative values of this instance and <paramref name="obj" />.</para> /// <list type="table"> /// <listheader> /// <term>Return Value</term> /// <description>Description</description> /// </listheader> /// <item> /// <term>Less than zero</term> /// <description>This instance is less than <paramref name="obj" />, or this instance is not a number and <paramref name="obj" /> is a number.</description> /// </item> /// <item> /// <term>Zero</term> /// <description>This instance is equal to <paramref name="obj" />, or both this instance and <paramref name="obj" /> are not a number.</description> /// </item> /// <item> /// <term>Greater than zero</term> /// <description>This instance is greater than <paramref name="obj" />, or this instance is a number and <paramref name="obj" /> is not a number or <paramref name="obj" /> is <c>null</c>.</description> /// </item> /// </list> /// </returns> /// <exception cref="ArgumentException"><paramref name="obj" /> is not a <see cref="NFloat" />.</exception> public int CompareTo(object? obj) { if (obj is NFloat other) { return CompareTo(other); } else if (obj is null) { return 1; } throw new ArgumentException(SR.Arg_MustBeNFloat); } /// <summary>Compares this instance to a specified floating-point number and returns an integer that indicates whether the value of this instance is less than, equal to, or greater than the value of the specified floating-point number.</summary> /// <param name="other">A floating-point number to compare.</param> /// <returns> /// <para>A signed number indicating the relative values of this instance and <paramref name="other" />.</para> /// <list type="table"> /// <listheader> /// <term>Return Value</term> /// <description>Description</description> /// </listheader> /// <item> /// <term>Less than zero</term> /// <description>This instance is less than <paramref name="other" />, or this instance is not a number and <paramref name="other" /> is a number.</description> /// </item> /// <item> /// <term>Zero</term> /// <description>This instance is equal to <paramref name="other" />, or both this instance and <paramref name="other" /> are not a number.</description> /// </item> /// <item> /// <term>Greater than zero</term> /// <description>This instance is greater than <paramref name="other" />, or this instance is a number and <paramref name="other" /> is not a number.</description> /// </item> /// </list> /// </returns> public int CompareTo(NFloat other) => _value.CompareTo(other._value); /// <summary>Returns a value indicating whether this instance is equal to a specified object.</summary> /// <param name="obj">An object to compare with this instance.</param> /// <returns><c>true</c> if <paramref name="obj"/> is an instance of <see cref="NFloat"/> and equals the value of this instance; otherwise, <c>false</c>.</returns> public override bool Equals([NotNullWhen(true)] object? obj) => (obj is NFloat other) && Equals(other); /// <summary>Returns a value indicating whether this instance is equal to a specified <see cref="NFloat" /> value.</summary> /// <param name="other">An <see cref="NFloat"/> value to compare to this instance.</param> /// <returns><c>true</c> if <paramref name="other"/> has the same value as this instance; otherwise, <c>false</c>.</returns> public bool Equals(NFloat other) => _value.Equals(other._value); /// <summary>Returns the hash code for this instance.</summary> /// <returns>A 32-bit signed integer hash code.</returns> public override int GetHashCode() => _value.GetHashCode(); /// <summary>Converts the numeric value of this instance to its equivalent string representation.</summary> /// <returns>The string representation of the value of this instance.</returns> public override string ToString() => _value.ToString(); /// <summary>Converts the numeric value of this instance to its equivalent string representation using the specified format.</summary> /// <param name="format">A numeric format string.</param> /// <returns>The string representation of the value of this instance as specified by <paramref name="format" />.</returns> /// <exception cref="FormatException"><paramref name="format" /> is invalid.</exception> public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format) => _value.ToString(format); /// <summary>Converts the numeric value of this instance to its equivalent string representation using the specified culture-specific format information.</summary> /// <param name="provider">An object that supplies culture-specific formatting information.</param> /// <returns>The string representation of the value of this instance as specified by <paramref name="provider" />.</returns> public string ToString(IFormatProvider? provider) => _value.ToString(provider); /// <summary>Converts the numeric value of this instance to its equivalent string representation using the specified format and culture-specific format information.</summary> /// <param name="format">A numeric format string.</param> /// <param name="provider">An object that supplies culture-specific formatting information.</param> /// <returns>The string representation of the value of this instance as specified by <paramref name="format" /> and <paramref name="provider" />.</returns> /// <exception cref="FormatException"><paramref name="format" /> is invalid.</exception> public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, IFormatProvider? provider) => _value.ToString(format, provider); /// <summary>Tries to format the value of the current instance into the provided span of characters.</summary> /// <param name="destination">The span in which to write this instance's value formatted as a span of characters.</param> /// <param name="charsWritten">When this method returns, contains the number of characters that were written in <paramref name="destination" />.</param> /// <param name="format">A span containing the characters that represent a standard or custom format string that defines the acceptable format for <paramref name="destination" />.</param> /// <param name="provider">An optional object that supplies culture-specific formatting information for <paramref name="destination" />.</param> /// <returns><c>true</c> if the formatting was successful; otherwise, <c>false</c>.</returns> public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) => _value.TryFormat(destination, out charsWritten, format, provider); /// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" /> public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) => _value.TryFormat(utf8Destination, out bytesWritten, format, provider); // // IAdditiveIdentity // /// <inheritdoc cref="IAdditiveIdentity{TSelf, TResult}.AdditiveIdentity" /> static NFloat IAdditiveIdentity<NFloat, NFloat>.AdditiveIdentity => new NFloat(NativeType.AdditiveIdentity); // // IBinaryNumber // /// <inheritdoc cref="IBinaryNumber{TSelf}.AllBitsSet" /> static NFloat IBinaryNumber<NFloat>.AllBitsSet { #if TARGET_64BIT [NonVersionable] get => (NFloat)BitConverter.UInt64BitsToDouble(0xFFFF_FFFF_FFFF_FFFF); #else [NonVersionable] get => BitConverter.UInt32BitsToSingle(0xFFFF_FFFF); #endif } /// <inheritdoc cref="IBinaryNumber{TSelf}.IsPow2(TSelf)" /> public static bool IsPow2(NFloat value) => NativeType.IsPow2(value._value); /// <inheritdoc cref="IBinaryNumber{TSelf}.Log2(TSelf)" /> public static NFloat Log2(NFloat value) => new NFloat(NativeType.Log2(value._value)); // // IBitwiseOperators // /// <inheritdoc cref="IBitwiseOperators{TSelf, TOther, TResult}.op_BitwiseAnd(TSelf, TOther)" /> static NFloat IBitwiseOperators<NFloat, NFloat, NFloat>.operator &(NFloat left, NFloat right) { #if TARGET_32BIT uint bits = BitConverter.SingleToUInt32Bits(left._value) & BitConverter.SingleToUInt32Bits(right._value); NativeType result = BitConverter.UInt32BitsToSingle(bits); return new NFloat(result); #else ulong bits = BitConverter.DoubleToUInt64Bits(left._value) & BitConverter.DoubleToUInt64Bits(right._value); NativeType result = BitConverter.UInt64BitsToDouble(bits); return new NFloat(result); #endif } /// <inheritdoc cref="IBitwiseOperators{TSelf, TOther, TResult}.op_BitwiseOr(TSelf, TOther)" /> static NFloat IBitwiseOperators<NFloat, NFloat, NFloat>.operator |(NFloat left, NFloat right) { #if TARGET_32BIT uint bits = BitConverter.SingleToUInt32Bits(left._value) | BitConverter.SingleToUInt32Bits(right._value); NativeType result = BitConverter.UInt32BitsToSingle(bits); return new NFloat(result); #else ulong bits = BitConverter.DoubleToUInt64Bits(left._value) | BitConverter.DoubleToUInt64Bits(right._value); NativeType result = BitConverter.UInt64BitsToDouble(bits); return new NFloat(result); #endif } /// <inheritdoc cref="IBitwiseOperators{TSelf, TOther, TResult}.op_ExclusiveOr(TSelf, TOther)" /> static NFloat IBitwiseOperators<NFloat, NFloat, NFloat>.operator ^(NFloat left, NFloat right) { #if TARGET_32BIT uint bits = BitConverter.SingleToUInt32Bits(left._value) ^ BitConverter.SingleToUInt32Bits(right._value); NativeType result = BitConverter.UInt32BitsToSingle(bits); return new NFloat(result); #else ulong bits = BitConverter.DoubleToUInt64Bits(left._value) ^ BitConverter.DoubleToUInt64Bits(right._value); NativeType result = BitConverter.UInt64BitsToDouble(bits); return new NFloat(result); #endif } /// <inheritdoc cref="IBitwiseOperators{TSelf, TOther, TResult}.op_OnesComplement(TSelf)" /> static NFloat IBitwiseOperators<NFloat, NFloat, NFloat>.operator ~(NFloat value) { #if TARGET_32BIT uint bits = ~BitConverter.SingleToUInt32Bits(value._value); NativeType result = BitConverter.UInt32BitsToSingle(bits); return new NFloat(result); #else ulong bits = ~BitConverter.DoubleToUInt64Bits(value._value); NativeType result = BitConverter.UInt64BitsToDouble(bits); return new NFloat(result); #endif } // // IExponentialFunctions // /// <inheritdoc cref="IExponentialFunctions{TSelf}.Exp" /> public static NFloat Exp(NFloat x) => new NFloat(NativeType.Exp(x._value)); /// <inheritdoc cref="IExponentialFunctions{TSelf}.ExpM1(TSelf)" /> public static NFloat ExpM1(NFloat x) => new NFloat(NativeType.ExpM1(x._value)); /// <inheritdoc cref="IExponentialFunctions{TSelf}.Exp2(TSelf)" /> public static NFloat Exp2(NFloat x) => new NFloat(NativeType.Exp2(x._value)); /// <inheritdoc cref="IExponentialFunctions{TSelf}.Exp2M1(TSelf)" /> public static NFloat Exp2M1(NFloat x) => new NFloat(NativeType.Exp2M1(x._value)); /// <inheritdoc cref="IExponentialFunctions{TSelf}.Exp10(TSelf)" /> public static NFloat Exp10(NFloat x) => new NFloat(NativeType.Exp10(x._value)); /// <inheritdoc cref="IExponentialFunctions{TSelf}.Exp10M1(TSelf)" /> public static NFloat Exp10M1(NFloat x) => new NFloat(NativeType.Exp10M1(x._value)); // // IFloatingPoint // /// <inheritdoc cref="IFloatingPoint{TSelf}.Ceiling(TSelf)" /> public static NFloat Ceiling(NFloat x) => new NFloat(NativeType.Ceiling(x._value)); /// <inheritdoc cref="IFloatingPoint{TSelf}.ConvertToInteger{TInteger}(TSelf)" /> public static TInteger ConvertToInteger<TInteger>(NFloat value) where TInteger : IBinaryInteger<TInteger> => TInteger.CreateSaturating(value); /// <inheritdoc cref="IFloatingPoint{TSelf}.ConvertToIntegerNative{TInteger}(TSelf)" /> public static TInteger ConvertToIntegerNative<TInteger>(NFloat value) where TInteger : IBinaryInteger<TInteger> => TInteger.CreateSaturating(value); /// <inheritdoc cref="IFloatingPoint{TSelf}.Floor(TSelf)" /> public static NFloat Floor(NFloat x) => new NFloat(NativeType.Floor(x._value)); /// <inheritdoc cref="IFloatingPoint{TSelf}.Round(TSelf)" /> public static NFloat Round(NFloat x) => new NFloat(NativeType.Round(x._value)); /// <inheritdoc cref="IFloatingPoint{TSelf}.Round(TSelf, int)" /> public static NFloat Round(NFloat x, int digits) => new NFloat(NativeType.Round(x._value, digits)); /// <inheritdoc cref="IFloatingPoint{TSelf}.Round(TSelf, MidpointRounding)" /> public static NFloat Round(NFloat x, MidpointRounding mode) => new NFloat(NativeType.Round(x._value, mode)); /// <inheritdoc cref="IFloatingPoint{TSelf}.Round(TSelf, int, MidpointRounding)" /> public static NFloat Round(NFloat x, int digits, MidpointRounding mode) => new NFloat(NativeType.Round(x._value, digits, mode)); /// <inheritdoc cref="IFloatingPoint{TSelf}.Truncate(TSelf)" /> public static NFloat Truncate(NFloat x) => new NFloat(NativeType.Truncate(x._value)); /// <inheritdoc cref="IFloatingPoint{TSelf}.GetExponentByteCount()" /> int IFloatingPoint<NFloat>.GetExponentByteCount() => sizeof(NativeExponentType); /// <inheritdoc cref="IFloatingPoint{TSelf}.GetExponentShortestBitLength()" /> int IFloatingPoint<NFloat>.GetExponentShortestBitLength() { NativeExponentType exponent = _value.Exponent; if (exponent >= 0) { return (sizeof(NativeExponentType) * 8) - NativeExponentType.LeadingZeroCount(exponent); } else { return (sizeof(NativeExponentType) * 8) + 1 - NativeExponentType.LeadingZeroCount((NativeExponentType)(~exponent)); } } /// <inheritdoc cref="IFloatingPoint{TSelf}.GetSignificandByteCount()" /> int IFloatingPoint<NFloat>.GetSignificandByteCount() => sizeof(NativeSignificandType); /// <inheritdoc cref="IFloatingPoint{TSelf}.GetSignificandBitLength()" /> int IFloatingPoint<NFloat>.GetSignificandBitLength() { #if TARGET_32BIT return 24; #else return 53; #endif } /// <inheritdoc cref="IFloatingPoint{TSelf}.TryWriteExponentBigEndian(Span{byte}, out int)" /> bool IFloatingPoint<NFloat>.TryWriteExponentBigEndian(Span<byte> destination, out int bytesWritten) { return _value.TryWriteExponentBigEndian(destination, out bytesWritten); } /// <inheritdoc cref="IFloatingPoint{TSelf}.TryWriteExponentLittleEndian(Span{byte}, out int)" /> bool IFloatingPoint<NFloat>.TryWriteExponentLittleEndian(Span<byte> destination, out int bytesWritten) { return _value.TryWriteExponentLittleEndian(destination, out bytesWritten); } /// <inheritdoc cref="IFloatingPoint{TSelf}.TryWriteSignificandBigEndian(Span{byte}, out int)" /> bool IFloatingPoint<NFloat>.TryWriteSignificandBigEndian(Span<byte> destination, out int bytesWritten) { return _value.TryWriteSignificandBigEndian(destination, out bytesWritten); } /// <inheritdoc cref="IFloatingPoint{TSelf}.TryWriteSignificandLittleEndian(Span{byte}, out int)" /> bool IFloatingPoint<NFloat>.TryWriteSignificandLittleEndian(Span<byte> destination, out int bytesWritten) { return _value.TryWriteSignificandLittleEndian(destination, out bytesWritten); } // // IFloatingPointConstants // /// <inheritdoc cref="IFloatingPointConstants{TSelf}.E" /> public static NFloat E => new NFloat(NativeType.E); /// <inheritdoc cref="IFloatingPointConstants{TSelf}.Pi" /> public static NFloat Pi => new NFloat(NativeType.Pi); /// <inheritdoc cref="IFloatingPointConstants{TSelf}.Tau" /> public static NFloat Tau => new NFloat(NativeType.Tau); // // IFloatingPointIeee754 // /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.NegativeZero" /> public static NFloat NegativeZero => new NFloat(NativeType.NegativeZero); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.Atan2(TSelf, TSelf)" /> public static NFloat Atan2(NFloat y, NFloat x) => new NFloat(NativeType.Atan2(y._value, x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.Atan2Pi(TSelf, TSelf)" /> public static NFloat Atan2Pi(NFloat y, NFloat x) => new NFloat(NativeType.Atan2Pi(y._value, x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.BitDecrement(TSelf)" /> public static NFloat BitDecrement(NFloat x) => new NFloat(NativeType.BitDecrement(x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.BitIncrement(TSelf)" /> public static NFloat BitIncrement(NFloat x) => new NFloat(NativeType.BitIncrement(x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.FusedMultiplyAdd(TSelf, TSelf, TSelf)" /> public static NFloat FusedMultiplyAdd(NFloat left, NFloat right, NFloat addend) => new NFloat(NativeType.FusedMultiplyAdd(left._value, right._value, addend._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.Ieee754Remainder(TSelf, TSelf)" /> public static NFloat Ieee754Remainder(NFloat left, NFloat right) => new NFloat(NativeType.Ieee754Remainder(left._value, right._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.ILogB(TSelf)" /> public static int ILogB(NFloat x) => NativeType.ILogB(x._value); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.Lerp(TSelf, TSelf, TSelf)" /> public static NFloat Lerp(NFloat value1, NFloat value2, NFloat amount) => new NFloat(NativeType.Lerp(value1._value, value2._value, amount._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.ReciprocalEstimate(TSelf)" /> public static NFloat ReciprocalEstimate(NFloat x) => new NFloat(NativeType.ReciprocalEstimate(x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.ReciprocalSqrtEstimate(TSelf)" /> public static NFloat ReciprocalSqrtEstimate(NFloat x) => new NFloat(NativeType.ReciprocalSqrtEstimate(x._value)); /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.ScaleB(TSelf, int)" /> public static NFloat ScaleB(NFloat x, int n) => new NFloat(NativeType.ScaleB(x._value, n)); // /// <inheritdoc cref="IFloatingPointIeee754{TSelf}.Compound(TSelf, TSelf)" /> // public static NFloat Compound(NFloat x, NFloat n) => new NFloat(NativeType.Compound(x._value, n._value)); // // IHyperbolicFunctions // /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Acosh(TSelf)" /> public static NFloat Acosh(NFloat x) => new NFloat(NativeType.Acosh(x._value)); /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Asinh(TSelf)" /> public static NFloat Asinh(NFloat x) => new NFloat(NativeType.Asinh(x._value)); /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Atanh(TSelf)" /> public static NFloat Atanh(NFloat x) => new NFloat(NativeType.Atanh(x._value)); /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Cosh(TSelf)" /> public static NFloat Cosh(NFloat x) => new NFloat(NativeType.Cosh(x._value)); /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Sinh(TSelf)" /> public static NFloat Sinh(NFloat x) => new NFloat(NativeType.Sinh(x._value)); /// <inheritdoc cref="IHyperbolicFunctions{TSelf}.Tanh(TSelf)" /> public static NFloat Tanh(NFloat x) => new NFloat(NativeType.Tanh(x._value)); // // ILogarithmicFunctions // /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.Log(TSelf)" /> public static NFloat Log(NFloat x) => new NFloat(NativeType.Log(x._value)); /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.Log(TSelf, TSelf)" /> public static NFloat Log(NFloat x, NFloat newBase) => new NFloat(NativeType.Log(x._value, newBase._value)); /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.LogP1(TSelf)" /> public static NFloat LogP1(NFloat x) => new NFloat(NativeType.LogP1(x._value)); /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.Log2P1(TSelf)" /> public static NFloat Log2P1(NFloat x) => new NFloat(NativeType.Log2P1(x._value)); /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.Log10(TSelf)" /> public static NFloat Log10(NFloat x) => new NFloat(NativeType.Log10(x._value)); /// <inheritdoc cref="ILogarithmicFunctions{TSelf}.Log10P1(TSelf)" /> public static NFloat Log10P1(NFloat x) => new NFloat(NativeType.Log10P1(x._value)); // // IMultiplicativeIdentity // /// <inheritdoc cref="IMultiplicativeIdentity{TSelf, TResult}.MultiplicativeIdentity" /> static NFloat IMultiplicativeIdentity<NFloat, NFloat>.MultiplicativeIdentity => new NFloat(NativeType.MultiplicativeIdentity); // // INumber // /// <inheritdoc cref="INumber{TSelf}.Clamp(TSelf, TSelf, TSelf)" /> public static NFloat Clamp(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.Clamp(value._value, min._value, max._value)); /// <inheritdoc cref="INumber{TSelf}.ClampNative(TSelf, TSelf, TSelf)" /> public static NFloat ClampNative(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.ClampNative(value._value, min._value, max._value)); /// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" /> public static NFloat CopySign(NFloat value, NFloat sign) => new NFloat(NativeType.CopySign(value._value, sign._value)); /// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" /> public static NFloat Max(NFloat x, NFloat y) => new NFloat(NativeType.Max(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.MaxNative(TSelf, TSelf)" /> public static NFloat MaxNative(NFloat x, NFloat y) => new NFloat(NativeType.MaxNative(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.MaxNumber(TSelf, TSelf)" /> public static NFloat MaxNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxNumber(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.Min(TSelf, TSelf)" /> public static NFloat Min(NFloat x, NFloat y) => new NFloat(NativeType.Min(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.MinNative(TSelf, TSelf)" /> public static NFloat MinNative(NFloat x, NFloat y) => new NFloat(NativeType.MinNative(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.MinNumber(TSelf, TSelf)" /> public static NFloat MinNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinNumber(x._value, y._value)); /// <inheritdoc cref="INumber{TSelf}.Sign(TSelf)" /> public static int Sign(NFloat value) => NativeType.Sign(value._value); // // INumberBase // /// <inheritdoc cref="INumberBase{TSelf}.One" /> static NFloat INumberBase<NFloat>.One => new NFloat(NativeType.One); /// <inheritdoc cref="INumberBase{TSelf}.Radix" /> static int INumberBase<NFloat>.Radix => 2; /// <inheritdoc cref="INumberBase{TSelf}.Zero" /> static NFloat INumberBase<NFloat>.Zero => new NFloat(NativeType.Zero); /// <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)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NFloat CreateChecked<TOther>(TOther value) where TOther : INumberBase<TOther> { NFloat result; if (typeof(TOther) == typeof(NFloat)) { result = (NFloat)(object)value; } else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToChecked(value, out result)) { ThrowHelper.ThrowNotSupportedException(); } return result; } /// <inheritdoc cref="INumberBase{TSelf}.CreateSaturating{TOther}(TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NFloat CreateSaturating<TOther>(TOther value) where TOther : INumberBase<TOther> { NFloat result; if (typeof(TOther) == typeof(NFloat)) { result = (NFloat)(object)value; } else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToSaturating(value, out result)) { ThrowHelper.ThrowNotSupportedException(); } return result; } /// <inheritdoc cref="INumberBase{TSelf}.CreateTruncating{TOther}(TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NFloat CreateTruncating<TOther>(TOther value) where TOther : INumberBase<TOther> { NFloat result; if (typeof(TOther) == typeof(NFloat)) { result = (NFloat)(object)value; } else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToTruncating(value, out result)) { ThrowHelper.ThrowNotSupportedException(); } return result; } /// <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}.MultiplyAddEstimate(TSelf, TSelf, TSelf)" /> public static NFloat MultiplyAddEstimate(NFloat left, NFloat right, NFloat addend) => new NFloat(NativeType.MultiplyAddEstimate(left._value, right._value, addend._value)); /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool INumberBase<NFloat>.TryConvertFromChecked<TOther>(TOther value, out NFloat result) { return TryConvertFrom(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 TryConvertFrom(value, out result); } /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromTruncating{TOther}(TOther, out TSelf)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool INumberBase<NFloat>.TryConvertFromTruncating<TOther>(TOther value, out NFloat result) { return TryConvertFrom(value, out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryConvertFrom<TOther>(TOther value, out NFloat result) where TOther : INumberBase<TOther> { if (typeof(TOther) == typeof(byte)) { byte actualValue = (byte)(object)value; result = actualValue; return true; } else if (typeof(TOther) == typeof(char)) { char actualValue = (char)(object)value; result = actualValue; return true; } else if (typeof(TOther) == typeof(decimal)) { decimal actualValue = (decimal)(object)value; result = (NFloat)actualValue; return true; } else if (typeof(TOther) == typeof(double)) { 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)) { 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 = (NFloat)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 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 = (NFloat)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<NFloat>.TryConvertToChecked<TOther>(NFloat value, [MaybeNullWhen(false)] out TOther result) { 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}.TryConvertToSaturating{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool INumberBase<NFloat>.TryConvertToSaturating<TOther>(NFloat value, [MaybeNullWhen(false)] out TOther result) { return TryConvertTo(value, out result); } /// <inheritdoc cref="INumberBase{TSelf}.TryConvertToTruncating{TOther}(TSelf, out TOther)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] static bool INumberBase<NFloat>.TryConvertToTruncating<TOther>(NFloat value, [MaybeNullWhen(false)] out TOther result) { return TryConvertTo(value, out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryConvertTo<TOther>(NFloat value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther> { 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; } } /// <inheritdoc cref="INumberBase{TSelf}.TryParsePartial(string, NumberStyles, IFormatProvider?, out TSelf, out int)" /> public static bool TryParsePartial([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out NFloat result, out int charsConsumed) { Unsafe.SkipInit(out result); NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return Number.TryParseFloat(s.AsSpan(), style | Number.AllowTrailingInvalidCharacters, NumberFormatInfo.GetInstance(provider), out Unsafe.As<NFloat, NativeType>(ref result), out charsConsumed); } /// <inheritdoc cref="INumberBase{TSelf}.TryParsePartial(ReadOnlySpan{char}, NumberStyles, IFormatProvider?, out TSelf, out int)" /> public static bool TryParsePartial(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out NFloat result, out int charsConsumed) { Unsafe.SkipInit(out result); NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return Number.TryParseFloat(s, style | Number.AllowTrailingInvalidCharacters, NumberFormatInfo.GetInstance(provider), out Unsafe.As<NFloat, NativeType>(ref result), out charsConsumed); } /// <inheritdoc cref="INumberBase{TSelf}.TryParsePartial(ReadOnlySpan{byte}, NumberStyles, IFormatProvider?, out TSelf, out int)" /> public static bool TryParsePartial(ReadOnlySpan<byte> utf8Text, NumberStyles style, IFormatProvider? provider, out NFloat result, out int bytesConsumed) { Unsafe.SkipInit(out result); NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return Number.TryParseFloat(utf8Text, style | Number.AllowTrailingInvalidCharacters, NumberFormatInfo.GetInstance(provider), out Unsafe.As<NFloat, NativeType>(ref result), out bytesConsumed); } // // IParsable // /// <inheritdoc cref="IParsable{TSelf}.TryParse(string?, IFormatProvider?, out TSelf)" /> public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out NFloat result) => TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider, out result); // // IPowerFunctions // /// <inheritdoc cref="IPowerFunctions{TSelf}.Pow(TSelf, TSelf)" /> public static NFloat Pow(NFloat x, NFloat y) => new NFloat(NativeType.Pow(x._value, y._value)); // // IRootFunctions // /// <inheritdoc cref="IRootFunctions{TSelf}.Cbrt(TSelf)" /> public static NFloat Cbrt(NFloat x) => new NFloat(NativeType.Cbrt(x._value)); /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" /> public static NFloat Hypot(NFloat x, NFloat y) => new NFloat(NativeType.Hypot(x._value, y._value)); /// <inheritdoc cref="IRootFunctions{TSelf}.RootN(TSelf, int)" /> public static NFloat RootN(NFloat x, int n) => new NFloat(NativeType.RootN(x._value, n)); /// <inheritdoc cref="IRootFunctions{TSelf}.Sqrt(TSelf)" /> public static NFloat Sqrt(NFloat x) => new NFloat(NativeType.Sqrt(x._value)); // // ISignedNumber // /// <inheritdoc cref="ISignedNumber{TSelf}.NegativeOne" /> static NFloat ISignedNumber<NFloat>.NegativeOne => new NFloat(NativeType.NegativeOne); // // ISpanParsable // /// <inheritdoc cref="ISpanParsable{TSelf}.Parse(ReadOnlySpan{char}, IFormatProvider?)" /> public static NFloat Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider); /// <inheritdoc cref="ISpanParsable{TSelf}.TryParse(ReadOnlySpan{char}, IFormatProvider?, out TSelf)" /> public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out NFloat result) => TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider, out result); // // ITrigonometricFunctions // /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Acos(TSelf)" /> public static NFloat Acos(NFloat x) => new NFloat(NativeType.Acos(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.AcosPi(TSelf)" /> public static NFloat AcosPi(NFloat x) => new NFloat(NativeType.AcosPi(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Asin(TSelf)" /> public static NFloat Asin(NFloat x) => new NFloat(NativeType.Asin(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.AsinPi(TSelf)" /> public static NFloat AsinPi(NFloat x) => new NFloat(NativeType.AsinPi(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Atan(TSelf)" /> public static NFloat Atan(NFloat x) => new NFloat(NativeType.Atan(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.AtanPi(TSelf)" /> public static NFloat AtanPi(NFloat x) => new NFloat(NativeType.AtanPi(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Cos(TSelf)" /> public static NFloat Cos(NFloat x) => new NFloat(NativeType.Cos(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.CosPi(TSelf)" /> public static NFloat CosPi(NFloat x) => new NFloat(NativeType.CosPi(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.DegreesToRadians(TSelf)" /> public static NFloat DegreesToRadians(NFloat degrees) { // NOTE: Don't change the algorithm without consulting the DIM // which elaborates on why this implementation was chosen return new NFloat(NativeType.DegreesToRadians(degrees._value)); } /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.RadiansToDegrees(TSelf)" /> public static NFloat RadiansToDegrees(NFloat radians) { // NOTE: Don't change the algorithm without consulting the DIM // which elaborates on why this implementation was chosen return new NFloat(NativeType.RadiansToDegrees(radians._value)); } /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Sin(TSelf)" /> public static NFloat Sin(NFloat x) => new NFloat(NativeType.Sin(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.SinCos(TSelf)" /> public static (NFloat Sin, NFloat Cos) SinCos(NFloat x) { var (sin, cos) = NativeType.SinCos(x._value); return (new NFloat(sin), new NFloat(cos)); } /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.SinCosPi(TSelf)" /> public static (NFloat SinPi, NFloat CosPi) SinCosPi(NFloat x) { var (sinPi, cosPi) = NativeType.SinCosPi(x._value); return (new NFloat(sinPi), new NFloat(cosPi)); } /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.SinPi(TSelf)" /> public static NFloat SinPi(NFloat x) => new NFloat(NativeType.SinPi(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.Tan(TSelf)" /> public static NFloat Tan(NFloat x) => new NFloat(NativeType.Tan(x._value)); /// <inheritdoc cref="ITrigonometricFunctions{TSelf}.TanPi(TSelf)" /> public static NFloat TanPi(NFloat x) => new NFloat(NativeType.TanPi(x._value)); // // IUtf8SpanParsable // /// <inheritdoc cref="INumberBase{TSelf}.Parse(ReadOnlySpan{byte}, NumberStyles, IFormatProvider?)" /> public static NFloat Parse(ReadOnlySpan<byte> utf8Text, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider? provider = null) { var result = NativeType.Parse(utf8Text, style, provider); return new NFloat(result); } /// <inheritdoc cref="INumberBase{TSelf}.TryParse(ReadOnlySpan{byte}, NumberStyles, IFormatProvider?, out TSelf)" /> public static bool TryParse(ReadOnlySpan<byte> utf8Text, NumberStyles style, IFormatProvider? provider, out NFloat result) { Unsafe.SkipInit(out result); return NativeType.TryParse(utf8Text, style, provider, out Unsafe.As<NFloat, NativeType>(ref result)); } /// <inheritdoc cref="IUtf8SpanParsable{TSelf}.Parse(ReadOnlySpan{byte}, IFormatProvider?)" /> public static NFloat Parse(ReadOnlySpan<byte> utf8Text, IFormatProvider? provider) => Parse(utf8Text, NumberStyles.Float | NumberStyles.AllowThousands, provider); /// <inheritdoc cref="IUtf8SpanParsable{TSelf}.TryParse(ReadOnlySpan{byte}, IFormatProvider?, out TSelf)" /> public static bool TryParse(ReadOnlySpan<byte> utf8Text, IFormatProvider? provider, out NFloat result) => TryParse(utf8Text, NumberStyles.Float | NumberStyles.AllowThousands, provider, out result); } }