Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
897fdb9
Adding barebones Int128 and UInt128 structs
tannergooding Apr 11, 2022
2fe1618
Special case Int128 and UInt128 alignment on x64 Unix and Arm64
tannergooding May 2, 2022
6559609
Implementing Int128 and UInt128
tannergooding May 3, 2022
2c820b5
Adding tests for Int128 and UInt128
tannergooding May 7, 2022
e7970fb
Updating Int128/UInt128 to respect the System V ABI ordering
tannergooding May 11, 2022
828440f
Merge remote-tracking branch 'dotnet/main' into generic-math-int128
tannergooding May 11, 2022
6904e73
Fixing an issue with UInt128->BigInteger setting the wrong sign
tannergooding May 12, 2022
bcbc375
Merge remote-tracking branch 'dotnet/main' into generic-math-int128
tannergooding May 12, 2022
09e8bfc
Don't use Unsafe.As in the Int128/UInt128 hex parsing logic
tannergooding May 12, 2022
5f9d22f
Adding Int128 P/Invoke tests and ensure R2R correctly sets the packing
tannergooding May 13, 2022
b6b85e6
Fixing some issues with the Int128 interop test for non-Windows
tannergooding May 13, 2022
9de4e76
Ensure that floating-point conversions exist for Int128 and UInt128
tannergooding May 13, 2022
a1dc14f
Fixing the casing of a couple fields
tannergooding May 16, 2022
7666952
Revert "Don't use Unsafe.As in the Int128/UInt128 hex parsing logic"
tannergooding May 16, 2022
f0a30cb
Adjusting the Int128/UInt128 generic math tests to have consistent or…
tannergooding May 16, 2022
cb5a82e
Responding to PR feedback
tannergooding May 18, 2022
384e572
Ensure that pNativeLayoutInfo alignment is initialized for Int128/UIn…
tannergooding May 18, 2022
ab85c7b
Don't use Unsafe.As in the Int128/UInt128 hex parsing logic
tannergooding May 12, 2022
163cfda
Merge remote-tracking branch 'dotnet/main' into generic-math-int128
tannergooding May 19, 2022
cd3c9e9
Skip the Interop/PInvoke/Int128 tests on Mono
tannergooding May 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Ensure that floating-point conversions exist for Int128 and UInt128
  • Loading branch information
tannergooding committed May 13, 2022
commit 9de4e76795a06e49e42844318a02c02657a57170
28 changes: 27 additions & 1 deletion THIRD-PARTY-NOTICES.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -1072,4 +1072,30 @@ Copyright (c) Microsoft Corporation.
Licensed under the MIT License.

Available at
https://github.com/microsoft/msquic/blob/main/LICENSE
https://github.com/microsoft/msquic/blob/main/LICENSE

License notice for m-ou-se/floatconv
-------------------------------

Copyright (c) 2020 Mara Bos <[email protected]>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public partial struct Decimal
internal uint Low => (uint)_lo64;
internal uint Mid => (uint)(_lo64 >> 32);

private ulong Low64 => _lo64;
internal ulong Low64 => _lo64;

private static ref DecCalc AsMutable(ref decimal d) => ref Unsafe.As<decimal, DecCalc>(ref d);

Expand Down
66 changes: 66 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Decimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,10 @@ public static decimal CreateChecked<TOther>(TOther value)
{
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;
Expand All @@ -1320,6 +1324,10 @@ public static decimal CreateChecked<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1364,6 +1372,12 @@ public static decimal CreateSaturating<TOther>(TOther value)
{
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;
Expand All @@ -1388,6 +1402,11 @@ public static decimal CreateSaturating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1432,6 +1451,21 @@ public static decimal CreateTruncating<TOther>(TOther value)
{
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;
Expand All @@ -1456,6 +1490,12 @@ public static decimal CreateTruncating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1531,6 +1571,19 @@ public static bool TryCreate<TOther>(TOther value, out decimal result)
result = (long)(object)value;
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;
return true;
}
else if (typeof(TOther) == typeof(nint))
{
result = (nint)(object)value;
Expand Down Expand Up @@ -1561,6 +1614,19 @@ public static bool TryCreate<TOther>(TOther value, out decimal result)
result = (ulong)(object)value;
return true;
}
else if (typeof(TOther) == typeof(UInt128))
{
var actualValue = (UInt128)(object)value;

if (actualValue > new UInt128(0x0000_0000_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF))
{
result = default;
return false;
}

result = (decimal)actualValue;
return true;
}
else if (typeof(TOther) == typeof(nuint))
{
result = (nuint)(object)value;
Expand Down
34 changes: 34 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Double.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,10 @@ public static double CreateChecked<TOther>(TOther value)
{
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;
Expand All @@ -1040,6 +1044,10 @@ public static double CreateChecked<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1084,6 +1092,10 @@ public static double CreateSaturating<TOther>(TOther value)
{
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;
Expand All @@ -1108,6 +1120,10 @@ public static double CreateSaturating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1152,6 +1168,10 @@ public static double CreateTruncating<TOther>(TOther value)
{
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;
Expand All @@ -1176,6 +1196,10 @@ public static double CreateTruncating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1242,6 +1266,11 @@ public static bool TryCreate<TOther>(TOther value, out double result)
result = (long)(object)value;
return true;
}
else if (typeof(TOther) == typeof(Int128))
{
result = (double)(Int128)(object)value;
return true;
}
else if (typeof(TOther) == typeof(nint))
{
result = (nint)(object)value;
Expand Down Expand Up @@ -1272,6 +1301,11 @@ public static bool TryCreate<TOther>(TOther value, out double result)
result = (ulong)(object)value;
return true;
}
else if (typeof(TOther) == typeof(UInt128))
{
result = (double)(UInt128)(object)value;
return true;
}
else if (typeof(TOther) == typeof(nuint))
{
result = (nuint)(object)value;
Expand Down
40 changes: 37 additions & 3 deletions src/libraries/System.Private.CoreLib/src/System/Half.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,10 @@ public static Half CreateChecked<TOther>(TOther value)
{
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;
Expand All @@ -1238,6 +1242,10 @@ public static Half CreateChecked<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1282,6 +1290,10 @@ public static Half CreateSaturating<TOther>(TOther value)
{
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;
Expand All @@ -1306,6 +1318,10 @@ public static Half CreateSaturating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1350,6 +1366,10 @@ public static Half CreateTruncating<TOther>(TOther value)
{
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;
Expand All @@ -1374,6 +1394,10 @@ public static Half CreateTruncating<TOther>(TOther value)
{
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;
Expand Down Expand Up @@ -1440,6 +1464,11 @@ public static bool TryCreate<TOther>(TOther value, out Half result)
result = (Half)(long)(object)value;
return true;
}
else if (typeof(TOther) == typeof(Int128))
{
result = (Half)(Int128)(object)value;
return true;
}
else if (typeof(TOther) == typeof(nint))
{
result = (Half)(long)(nint)(object)value;
Expand Down Expand Up @@ -1470,6 +1499,11 @@ public static bool TryCreate<TOther>(TOther value, out Half result)
result = (Half)(ulong)(object)value;
return true;
}
else if (typeof(TOther) == typeof(UInt128))
{
result = (Half)(UInt128)(object)value;
return true;
}
else if (typeof(TOther) == typeof(nuint))
{
result = (Half)(ulong)(nuint)(object)value;
Expand All @@ -1488,10 +1522,10 @@ public static bool TryCreate<TOther>(TOther value, out Half result)
//

/// <inheritdoc cref="INumberBase{TSelf}.One" />
static Half INumberBase<Half>.One => new Half(PositiveOneBits);
public static Half One => new Half(PositiveOneBits);

/// <inheritdoc cref="INumberBase{TSelf}.Zero" />
static Half INumberBase<Half>.Zero => new Half(PositiveZeroBits);
public static Half Zero => new Half(PositiveZeroBits);

//
// IParsable
Expand Down Expand Up @@ -1527,7 +1561,7 @@ public static bool TryCreate<TOther>(TOther value, out Half result)
//

/// <inheritdoc cref="ISignedNumber{TSelf}.NegativeOne" />
static Half ISignedNumber<Half>.NegativeOne => new Half(NegativeOneBits);
public static Half NegativeOne => new Half(NegativeOneBits);

//
// ISpanParsable
Expand Down
Loading