Imported Upstream version 5.2.0.175

Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-06-07 13:16:24 +00:00
parent 4bdbaf4a88
commit 966bba02bb
8776 changed files with 346420 additions and 149650 deletions

View File

@@ -1,7 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Numerics.Tests", "tests\System.Runtime.Numerics.Tests.csproj", "{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}"
ProjectSection(ProjectDependencies) = postProject
@@ -9,53 +8,43 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Numerics.Tes
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Numerics", "src\System.Runtime.Numerics.csproj", "{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}"
ProjectSection(ProjectDependencies) = postProject
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F} = {7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Numerics", "ref\System.Runtime.Numerics.csproj", "{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1A2F9F4A-A032-433E-B914-ADD5992BB178}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU
ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnetcoreappnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{28AE24F8-BEF4-4358-B612-ADD9D587C8E1} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
EndGlobalSection
EndGlobal

View File

@@ -4,5 +4,6 @@
<PropertyGroup>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<IsNETCoreApp>true</IsNETCoreApp>
<IsUAP>true</IsUAP>
</PropertyGroup>
</Project>

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{7D5CBF2F-337C-4AEB-B035-A17D33A9BC1F}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />

View File

@@ -2,7 +2,7 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
net463-Windows_NT;
uap-Windows_NT;
netcoreapp;
</BuildConfigurations>
</PropertyGroup>

View File

@@ -1,64 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">

View File

@@ -7,15 +7,13 @@
<AssemblyName>System.Runtime.Numerics</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProjectGuid>{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}</ProjectGuid>
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'net463'">true</IsPartialFacadeAssembly>
<ResourcesSourceOutputDirectory Condition="'$(TargetGroup)' == 'net463'">None</ResourcesSourceOutputDirectory>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Release|AnyCPU'" />
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="System\Numerics\BigIntegerCalculator.AddSub.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.BitsBuffer.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.DivRem.cs" />
@@ -33,10 +31,6 @@
<Link>System\Globalization\FormatProvider.Number.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'net463'">
<TargetingPackReference Include="mscorlib" />
<TargetingPackReference Include="System.Numerics" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Diagnostics.Contracts" />
<Reference Include="System.Diagnostics.Debug" />

View File

@@ -76,7 +76,7 @@ namespace System.Numerics
ulong x = 0;
if (value < 0)
{
x = (ulong)-value;
x = unchecked((ulong)-value);
_sign = -1;
}
else
@@ -93,7 +93,7 @@ namespace System.Numerics
else
{
_bits = new uint[2];
_bits[0] = (uint)x;
_bits[0] = unchecked((uint)x);
_bits[1] = (uint)(x >> kcbitUint);
}
}
@@ -119,7 +119,7 @@ namespace System.Numerics
{
_sign = +1;
_bits = new uint[2];
_bits[0] = (uint)value;
_bits[0] = unchecked((uint)value);
_bits[1] = (uint)(value >> kcbitUint);
}
@@ -189,9 +189,9 @@ namespace System.Numerics
// Populate the uints.
_bits = new uint[cu + 2];
_bits[cu + 1] = (uint)(man >> (cbit + kcbitUint));
_bits[cu] = (uint)(man >> cbit);
_bits[cu] = unchecked((uint)(man >> cbit));
if (cbit > 0)
_bits[cu - 1] = (uint)man << (kcbitUint - cbit);
_bits[cu - 1] = unchecked((uint)man) << (kcbitUint - cbit);
_sign = sign;
}
@@ -223,11 +223,16 @@ namespace System.Numerics
else
{
_bits = new uint[size];
_bits[0] = (uint)bits[0];
if (size > 1)
_bits[1] = (uint)bits[1];
if (size > 2)
_bits[2] = (uint)bits[2];
unchecked
{
_bits[0] = (uint)bits[0];
if (size > 1)
_bits[1] = (uint)bits[1];
if (size > 2)
_bits[2] = (uint)bits[2];
}
_sign = ((bits[3] & DecimalSignMask) != 0) ? -1 : +1;
}
AssertValid();
@@ -279,7 +284,7 @@ namespace System.Numerics
// can be naively packed into 4 bytes (due to the leading 0x0)
// it overflows into the int32 sign bit
_bits = new uint[1];
_bits[0] = (uint)_sign;
_bits[0] = unchecked((uint)_sign);
_sign = +1;
}
if (_sign == int.MinValue)
@@ -333,7 +338,7 @@ namespace System.Numerics
int len = val.Length;
while (len > 0 && val[len - 1] == 0)
len--;
if (len == 1 && ((int)(val[0])) > 0)
if (len == 1 && unchecked((int)(val[0])) > 0)
{
if (val[0] == 1 /* abs(-1) */)
{
@@ -441,20 +446,20 @@ namespace System.Numerics
}
if (dwordCount == 1)
{
if ((int)value[0] < 0 && !isNegative)
if (unchecked((int)value[0]) < 0 && !isNegative)
{
_bits = new uint[1];
_bits[0] = value[0];
_sign = +1;
}
// Handle the special cases where the BigInteger likely fits into _sign
else if (int.MinValue == (int)value[0])
else if (int.MinValue == unchecked((int)value[0]))
{
this = s_bnMinInt;
}
else
{
_sign = (int)value[0];
_sign = unchecked((int)value[0]);
_bits = null;
}
AssertValid();
@@ -488,7 +493,7 @@ namespace System.Numerics
while (len > 0 && value[len - 1] == 0) len--;
// The number is represented by a single dword
if (len == 1 && ((int)(value[0])) > 0)
if (len == 1 && unchecked((int)(value[0])) > 0)
{
if (value[0] == 1 /* abs(-1) */)
{
@@ -865,7 +870,7 @@ namespace System.Numerics
return _sign;
int hash = _sign;
for (int iv = _bits.Length; --iv >= 0;)
hash = NumericsHelpers.CombineHash(hash, (int)_bits[iv]);
hash = NumericsHelpers.CombineHash(hash, unchecked((int)_bits[iv]));
return hash;
}
@@ -1140,7 +1145,7 @@ namespace System.Numerics
if (_bits == null)
{
dwords = new uint[] { (uint)_sign };
dwords = new uint[] { unchecked((uint)_sign) };
highDWord = (_sign < 0) ? uint.MaxValue : 0;
}
else if (_sign == -1)
@@ -1416,7 +1421,7 @@ namespace System.Numerics
uu = value._bits[0];
}
long ll = value._sign > 0 ? (long)uu : -(long)uu;
long ll = value._sign > 0 ? unchecked((long)uu) : unchecked(-(long)uu);
if ((ll > 0 && value._sign > 0) || (ll < 0 && value._sign < 0))
{
// Signs match, no overflow
@@ -1499,9 +1504,13 @@ namespace System.Numerics
if (length > 3) throw new OverflowException(SR.Overflow_Decimal);
int lo = 0, mi = 0, hi = 0;
if (length > 2) hi = (int)value._bits[2];
if (length > 1) mi = (int)value._bits[1];
if (length > 0) lo = (int)value._bits[0];
unchecked
{
if (length > 2) hi = (int)value._bits[2];
if (length > 1) mi = (int)value._bits[1];
if (length > 0) lo = (int)value._bits[0];
}
return new decimal(lo, mi, hi, value._sign < 0, 0);
}
@@ -1513,6 +1522,11 @@ namespace System.Numerics
return Zero;
}
if (left._bits == null && right._bits == null)
{
return left._sign & right._sign;
}
uint[] x = left.ToUInt32Array();
uint[] y = right.ToUInt32Array();
uint[] z = new uint[Math.Max(x.Length, y.Length)];
@@ -1534,6 +1548,11 @@ namespace System.Numerics
return right;
if (right.IsZero)
return left;
if (left._bits == null && right._bits == null)
{
return left._sign | right._sign;
}
uint[] x = left.ToUInt32Array();
uint[] y = right.ToUInt32Array();
@@ -1552,6 +1571,11 @@ namespace System.Numerics
public static BigInteger operator ^(BigInteger left, BigInteger right)
{
if (left._bits == null && right._bits == null)
{
return left._sign ^ right._sign;
}
uint[] x = left.ToUInt32Array();
uint[] y = right.ToUInt32Array();
uint[] z = new uint[Math.Max(x.Length, y.Length)];

View File

@@ -21,13 +21,13 @@ namespace System.Numerics
uint[] bits = new uint[left.Length + 1];
long digit = (long)left[0] + right;
bits[0] = (uint)digit;
bits[0] = unchecked((uint)digit);
long carry = digit >> 32;
for (int i = 1; i < left.Length; i++)
{
digit = left[i] + carry;
bits[i] = (uint)digit;
bits[i] = unchecked((uint)digit);
carry = digit >> 32;
}
bits[left.Length] = (uint)carry;
@@ -47,7 +47,7 @@ namespace System.Numerics
uint[] bits = new uint[left.Length + 1];
fixed (uint* l = left, r = right, b = bits)
fixed (uint* l = left, r = right, b = &bits[0])
{
Add(l, left.Length,
r, right.Length,
@@ -78,13 +78,13 @@ namespace System.Numerics
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) + right[i];
bits[i] = (uint)digit;
bits[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; i < leftLength; i++)
{
long digit = left[i] + carry;
bits[i] = (uint)digit;
bits[i] = unchecked((uint)digit);
carry = digit >> 32;
}
bits[i] = (uint)carry;
@@ -108,7 +108,7 @@ namespace System.Numerics
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) + right[i];
left[i] = (uint)digit;
left[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; carry != 0 && i < leftLength; i++)
@@ -134,13 +134,13 @@ namespace System.Numerics
uint[] bits = new uint[left.Length];
long digit = (long)left[0] - right;
bits[0] = (uint)digit;
bits[0] = unchecked((uint)digit);
long carry = digit >> 32;
for (int i = 1; i < left.Length; i++)
{
digit = left[i] + carry;
bits[i] = (uint)digit;
bits[i] = unchecked((uint)digit);
carry = digit >> 32;
}
@@ -192,7 +192,7 @@ namespace System.Numerics
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) - right[i];
bits[i] = (uint)digit;
bits[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; i < leftLength; i++)
@@ -224,7 +224,7 @@ namespace System.Numerics
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) - right[i];
left[i] = (uint)digit;
left[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; carry != 0 && i < leftLength; i++)

View File

@@ -7,14 +7,17 @@ using System.Security;
namespace System.Numerics
{
// ATTENTION: always pass BitsBuffer by reference,
// it's a structure for performance reasons. Furthermore
// it's a mutable one, so use it only with care!
internal static partial class BigIntegerCalculator
{
/// <summary>
/// To spare memory allocations a buffer helps reusing memory!
/// We just create the target array twice and switch between every
/// operation. In order to not compute unnecessarily with all those
/// leading zeros we take care of the current actual length.
/// </summary>
// To spare memory allocations a buffer helps reusing memory!
// We just create the target array twice and switch between every
// operation. In order to not compute unnecessarily with all those
// leading zeros we take care of the current actual length.
internal struct BitsBuffer
{
private uint[] _bits;
@@ -92,6 +95,7 @@ namespace System.Numerics
{
// Executes a modulo operation using an optimized reducer.
// Thus, no need of any switching here, happens in-line.
_length = reducer.Reduce(_bits, _length);
}
@@ -121,6 +125,7 @@ namespace System.Numerics
{
// Executes a modulo operation using the divide operation.
// Thus, no need of any switching here, happens in-line.
if (_length >= modulus._length)
{
fixed (uint* b = _bits, m = modulus._bits)
@@ -144,7 +149,7 @@ namespace System.Numerics
Array.Clear(_bits, 2, _length - 2);
}
uint lo = (uint)value;
uint lo = unchecked((uint)value);
uint hi = (uint)(value >> 32);
_bits[0] = lo;
@@ -201,6 +206,7 @@ namespace System.Numerics
// Resets this and switches this and temp afterwards.
// The caller assumed an empty temp, the next will too.
Array.Clear(_bits, 0, _length);
uint[] t = temp._bits;

View File

@@ -40,6 +40,7 @@ namespace System.Numerics
Debug.Assert(left.Length >= 1);
// Same as above, but only computing the quotient.
uint[] quotient = new uint[left.Length];
ulong carry = 0UL;
@@ -60,6 +61,7 @@ namespace System.Numerics
Debug.Assert(left.Length >= 1);
// Same as above, but only computing the remainder.
ulong carry = 0UL;
for (int i = left.Length - 1; i >= 0; i--)
{
@@ -88,7 +90,7 @@ namespace System.Numerics
uint[] localLeft = CreateCopy(left);
uint[] bits = new uint[left.Length - right.Length + 1];
fixed (uint* l = localLeft, r = right, b = bits)
fixed (uint* l = &localLeft[0], r = &right[0], b = &bits[0])
{
Divide(l, localLeft.Length,
r, right.Length,
@@ -110,11 +112,13 @@ namespace System.Numerics
Debug.Assert(left.Length >= right.Length);
// Same as above, but only returning the quotient.
// NOTE: left will get overwritten, we need a local copy
uint[] localLeft = CreateCopy(left);
uint[] bits = new uint[left.Length - right.Length + 1];
fixed (uint* l = localLeft, r = right, b = bits)
fixed (uint* l = &localLeft[0], r = &right[0], b = &bits[0])
{
Divide(l, localLeft.Length,
r, right.Length,
@@ -134,10 +138,12 @@ namespace System.Numerics
Debug.Assert(left.Length >= right.Length);
// Same as above, but only returning the remainder.
// NOTE: left will get overwritten, we need a local copy
uint[] localLeft = CreateCopy(left);
fixed (uint* l = localLeft, r = right)
fixed (uint* l = &localLeft[0], r = &right[0])
{
Divide(l, localLeft.Length,
r, right.Length,
@@ -243,12 +249,13 @@ namespace System.Numerics
Debug.Assert(leftLength >= rightLength);
// Repairs the dividend, if the last subtract was too much
ulong carry = 0UL;
for (int i = 0; i < rightLength; i++)
{
ulong digit = (left[i] + carry) + right[i];
left[i] = (uint)digit;
left[i] = unchecked((uint)digit);
carry = digit >> 32;
}
@@ -273,11 +280,11 @@ namespace System.Numerics
for (int i = 0; i < rightLength; i++)
{
carry += right[i] * q;
uint digit = (uint)carry;
uint digit = unchecked((uint)carry);
carry = carry >> 32;
if (left[i] < digit)
++carry;
left[i] -= digit;
left[i] = unchecked(left[i] - digit);
}
return (uint)carry;

View File

@@ -9,12 +9,12 @@ namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
/// <summary>
/// If we need to reduce by a certain modulus again and again, it's much
/// more efficient to do this with multiplication operations. This is
/// possible, if we do some pre-computations first...
/// see https://en.wikipedia.org/wiki/Barrett_reduction
/// </summary>
// If we need to reduce by a certain modulus again and again, it's much
// more efficient to do this with multiplication operations. This is
// possible, if we do some pre-computations first...
// see https://en.wikipedia.org/wiki/Barrett_reduction
internal struct FastReducer
{
private readonly uint[] _modulus;

View File

@@ -11,7 +11,9 @@ namespace System.Numerics
public static uint Gcd(uint left, uint right)
{
// Executes the classic Euclidean algorithm.
// https://en.wikipedia.org/wiki/Euclidean_algorithm
while (right != 0)
{
uint temp = left % right;
@@ -25,6 +27,7 @@ namespace System.Numerics
public static ulong Gcd(ulong left, ulong right)
{
// Same as above, but for 64-bit values.
while (right > 0xFFFFFFFF)
{
ulong temp = left % right;
@@ -269,8 +272,8 @@ namespace System.Numerics
long yDigit = d * y[i] - c * x[i] + yCarry;
xCarry = xDigit >> 32;
yCarry = yDigit >> 32;
x[i] = (uint)xDigit;
y[i] = (uint)yDigit;
x[i] = unchecked((uint)xDigit);
y[i] = unchecked((uint)yDigit);
}
xBuffer.Refresh(length);

View File

@@ -8,11 +8,11 @@ namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
/// <summary>
/// Executes different exponentiation algorithms, which are
/// basically based on the classic square-and-multiply method.
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
/// </summary>
// Executes different exponentiation algorithms, which are
// based on the classic square-and-multiply method.
// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
public static uint[] Pow(uint value, uint power)
{
// The basic pow method for a 32-bit integer.
@@ -31,6 +31,7 @@ namespace System.Numerics
// The basic pow method for a big integer.
// To spare memory allocations we first roughly
// estimate an upper bound for our buffers.
int size = PowBound(power, value.Length, 1);
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, ref v);
@@ -39,6 +40,7 @@ namespace System.Numerics
private static uint[] PowCore(uint power, ref BitsBuffer value)
{
// Executes the basic pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
@@ -54,6 +56,7 @@ namespace System.Numerics
{
// The basic pow algorithm, but instead of squaring
// and multiplying we just sum up the lengths.
while (power != 0)
{
checked
@@ -73,6 +76,7 @@ namespace System.Numerics
ref BitsBuffer result, ref BitsBuffer temp)
{
// The basic pow algorithm using square-and-multiply.
while (power != 0)
{
if ((power & 1) == 1)
@@ -87,6 +91,7 @@ namespace System.Numerics
{
// The 32-bit modulus pow method for a 32-bit integer
// raised by a 32-bit integer...
return PowCore(power, modulus, value, 1);
}
@@ -96,6 +101,7 @@ namespace System.Numerics
// The 32-bit modulus pow method for a big integer
// raised by a 32-bit integer...
uint v = Remainder(value, modulus);
return PowCore(power, modulus, v, 1);
}
@@ -106,6 +112,7 @@ namespace System.Numerics
// The 32-bit modulus pow method for a 32-bit integer
// raised by a big integer...
return PowCore(power, modulus, value, 1);
}
@@ -116,6 +123,7 @@ namespace System.Numerics
// The 32-bit modulus pow method for a big integer
// raised by a big integer...
uint v = Remainder(value, modulus);
return PowCore(power, modulus, v, 1);
}
@@ -125,6 +133,7 @@ namespace System.Numerics
{
// The 32-bit modulus pow algorithm for all but
// the last power limb using square-and-multiply.
for (int i = 0; i < power.Length - 1; i++)
{
uint p = power[i];
@@ -145,6 +154,7 @@ namespace System.Numerics
{
// The 32-bit modulus pow algorithm for the last or
// the only power limb using square-and-multiply.
while (power != 0)
{
if ((power & 1) == 1)
@@ -163,6 +173,7 @@ namespace System.Numerics
// The big modulus pow method for a 32-bit integer
// raised by a 32-bit integer...
int size = modulus.Length + modulus.Length;
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, modulus, ref v);
@@ -221,6 +232,7 @@ namespace System.Numerics
ref BitsBuffer value)
{
// Executes the big pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
@@ -243,6 +255,7 @@ namespace System.Numerics
ref BitsBuffer value)
{
// Executes the big pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
@@ -267,8 +280,10 @@ namespace System.Numerics
{
// The big modulus pow algorithm for all but
// the last power limb using square-and-multiply.
// NOTE: we're using an ordinary remainder here,
// since the reducer overhead doesn't pay off.
for (int i = 0; i < power.Length - 1; i++)
{
uint p = power[i];
@@ -295,8 +310,10 @@ namespace System.Numerics
{
// The big modulus pow algorithm for the last or
// the only power limb using square-and-multiply.
// NOTE: we're using an ordinary remainder here,
// since the reducer overhead doesn't pay off.
while (power != 0)
{
if ((power & 1) == 1)
@@ -313,12 +330,16 @@ namespace System.Numerics
}
}
private static void PowCore(uint[] power, ref FastReducer reducer, ref BitsBuffer value, ref BitsBuffer result, ref BitsBuffer temp)
private static void PowCore(uint[] power, ref FastReducer reducer,
ref BitsBuffer value, ref BitsBuffer result,
ref BitsBuffer temp)
{
// The big modulus pow algorithm for all but
// the last power limb using square-and-multiply.
// NOTE: we're using a special reducer here,
// since it's additional overhead does pay off.
for (int i = 0; i < power.Length - 1; i++)
{
uint p = power[i];
@@ -345,8 +366,10 @@ namespace System.Numerics
{
// The big modulus pow algorithm for the last or
// the only power limb using square-and-multiply.
// NOTE: we're using a special reducer here,
// since it's additional overhead does pay off.
while (power != 0)
{
if ((power & 1) == 1)
@@ -367,6 +390,7 @@ namespace System.Numerics
{
// Since we're reusing memory here, the actual length
// of a given value may be less then the array's length
return ActualLength(value, value.Length);
}

View File

@@ -69,11 +69,11 @@ namespace System.Numerics
{
ulong digit1 = bits[i + j] + carry;
ulong digit2 = (ulong)value[j] * value[i];
bits[i + j] = (uint)(digit1 + (digit2 << 1));
bits[i + j] = unchecked((uint)(digit1 + (digit2 << 1)));
carry = (digit2 + (digit1 >> 1)) >> 31;
}
ulong digits = (ulong)value[i] * value[i] + carry;
bits[i + i] = (uint)digits;
bits[i + i] = unchecked((uint)digits);
bits[i + i + 1] = (uint)(digits >> 32);
}
}
@@ -177,7 +177,7 @@ namespace System.Numerics
for (; i < left.Length; i++)
{
ulong digits = (ulong)left[i] * right + carry;
bits[i] = (uint)digits;
bits[i] = unchecked((uint)digits);
carry = digits >> 32;
}
bits[i] = (uint)carry;
@@ -245,7 +245,7 @@ namespace System.Numerics
{
ulong digits = bits[i + j] + carry
+ (ulong)left[j] * right[i];
bits[i + j] = (uint)digits;
bits[i + j] = unchecked((uint)digits);
carry = digits >> 32;
}
bits[i + leftLength] = (uint)carry;
@@ -382,13 +382,13 @@ namespace System.Numerics
for (; i < rightLength; i++)
{
long digit = (core[i] + carry) - left[i] - right[i];
core[i] = (uint)digit;
core[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; i < leftLength; i++)
{
long digit = (core[i] + carry) - left[i];
core[i] = (uint)digit;
core[i] = unchecked((uint)digit);
carry = digit >> 32;
}
for (; carry != 0 && i < coreLength; i++)

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Globalization;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace System.Numerics
@@ -23,6 +24,12 @@ namespace System.Numerics
// This is the largest x for which (Hypot(x,x) + x) will not overflow. It is used for branching inside Sqrt.
private static readonly double s_sqrtRescaleThreshold = double.MaxValue / (Math.Sqrt(2.0) + 1.0);
// This is the largest x for which 2 x^2 will not overflow. It is used for branching inside Asin and Acos.
private static readonly double s_asinOverflowThreshold = Math.Sqrt(double.MaxValue) / 2.0;
// This value is used inside Asin and Acos.
private static readonly double s_log2 = Math.Log(2.0);
private double _real;
private double _imaginary;
@@ -155,6 +162,33 @@ namespace System.Numerics
}
private static double Log1P(double x)
{
// Compute log(1 + x) without loss of accuracy when x is small.
// Our only use case so far is for positive values, so this isn't coded to handle negative values.
Debug.Assert((x >= 0.0) || double.IsNaN(x));
double xp1 = 1.0 + x;
if (xp1 == 1.0)
{
return x;
}
else if (x < 0.75)
{
// This is accurate to within 5 ulp with any floating-point system that uses a guard digit,
// as proven in Theorem 4 of "What Every Computer Scientist Should Know About Floating-Point
// Arithmetic" (https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
return x * Math.Log(xp1) / (xp1 - 1.0);
}
else
{
return Math.Log(xp1);
}
}
public static Complex Conjugate(Complex value)
{
// Conjugate of a Complex number: the conjugate of x+i*y is x-i*y
@@ -223,61 +257,119 @@ namespace System.Numerics
public static Complex Sin(Complex value)
{
double a = value._real;
double b = value._imaginary;
return new Complex(Math.Sin(a) * Math.Cosh(b), Math.Cos(a) * Math.Sinh(b));
// We need both sinh and cosh of imaginary part. To avoid multiple calls to Math.Exp with the same value,
// we compute them both here from a single call to Math.Exp.
double p = Math.Exp(value._imaginary);
double q = 1.0 / p;
double sinh = (p - q) * 0.5;
double cosh = (p + q) * 0.5;
return new Complex(Math.Sin(value._real) * cosh, Math.Cos(value._real) * sinh);
// There is a known limitation with this algorithm: inputs that cause sinh and cosh to overflow, but for
// which sin or cos are small enough that sin * cosh or cos * sinh are still representable, nonetheless
// produce overflow. For example, Sin((0.01, 711.0)) should produce (~3.0E306, PositiveInfinity), but
// instead produces (PositiveInfinity, PositiveInfinity).
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sinh", Justification = "Sinh is the name of a mathematical function.")]
public static Complex Sinh(Complex value)
{
double a = value._real;
double b = value._imaginary;
return new Complex(Math.Sinh(a) * Math.Cos(b), Math.Cosh(a) * Math.Sin(b));
// Use sinh(z) = -i sin(iz) to compute via sin(z).
Complex sin = Sin(new Complex(-value._imaginary, value._real));
return new Complex(sin._imaginary, -sin._real);
}
public static Complex Asin(Complex value)
{
if ((value._imaginary == 0 && value._real < 0) || value._imaginary > 0)
double b, bPrime, v;
Asin_Internal(Math.Abs(value.Real), Math.Abs(value.Imaginary), out b, out bPrime, out v);
double u;
if (bPrime < 0.0)
{
return -Asin(-value);
u = Math.Asin(b);
}
return (-ImaginaryOne) * Log(ImaginaryOne * value + Sqrt(One - value * value));
else
{
u = Math.Atan(bPrime);
}
if (value.Real < 0.0) u = -u;
if (value.Imaginary < 0.0) v = -v;
return new Complex(u, v);
}
public static Complex Cos(Complex value)
{
double a = value._real;
double b = value._imaginary;
return new Complex(Math.Cos(a) * Math.Cosh(b), -(Math.Sin(a) * Math.Sinh(b)));
public static Complex Cos(Complex value) {
double p = Math.Exp(value._imaginary);
double q = 1.0 / p;
double sinh = (p - q) * 0.5;
double cosh = (p + q) * 0.5;
return new Complex(Math.Cos(value._real) * cosh, -Math.Sin(value._real) * sinh);
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cosh", Justification = "Cosh is the name of a mathematical function.")]
public static Complex Cosh(Complex value)
{
double a = value._real;
double b = value._imaginary;
return new Complex(Math.Cosh(a) * Math.Cos(b), Math.Sinh(a) * Math.Sin(b));
// Use cosh(z) = cos(iz) to compute via cos(z).
return Cos(new Complex(-value._imaginary, value._real));
}
public static Complex Acos(Complex value)
{
if ((value._imaginary == 0 && value._real > 0) || value._imaginary < 0)
double b, bPrime, v;
Asin_Internal(Math.Abs(value.Real), Math.Abs(value.Imaginary), out b, out bPrime, out v);
double u;
if (bPrime < 0.0)
{
return Math.PI - Acos(-value);
u = Math.Acos(b);
}
return (-ImaginaryOne) * Log(value + ImaginaryOne * Sqrt(One - (value * value)));
else
{
u = Math.Atan(1.0 / bPrime);
}
if (value.Real < 0.0) u = Math.PI - u;
if (value.Imaginary > 0.0) v = -v;
return new Complex(u, v);
}
public static Complex Tan(Complex value)
{
return (Sin(value) / Cos(value));
// tan z = sin z / cos z, but to avoid unnecessary repeated trig computations, use
// tan z = (sin(2x) + i sinh(2y)) / (cos(2x) + cosh(2y))
// (see Abramowitz & Stegun 4.3.57 or derive by hand), and compute trig functions here.
// This approach does not work for |y| > ~355, because sinh(2y) and cosh(2y) overflow,
// even though their ratio does not. In that case, divide through by cosh to get:
// tan z = (sin(2x) / cosh(2y) + i \tanh(2y)) / (1 + cos(2x) / cosh(2y))
// which correctly computes the (tiny) real part and the (normal-sized) imaginary part.
double x2 = 2.0 * value._real;
double y2 = 2.0 * value._imaginary;
double p = Math.Exp(y2);
double q = 1.0 / p;
double cosh = (p + q) * 0.5;
if (Math.Abs(value._imaginary) <= 4.0)
{
double sinh = (p - q) * 0.5;
double D = Math.Cos(x2) + cosh;
return new Complex(Math.Sin(x2) / D, sinh / D);
}
else
{
double D = 1.0 + Math.Cos(x2) / cosh;
return new Complex(Math.Sin(x2) / cosh / D, Math.Tanh(y2) / D);
}
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tanh", Justification = "Tanh is the name of a mathematical function.")]
public static Complex Tanh(Complex value)
{
return (Sinh(value) / Cosh(value));
// Use tanh(z) = -i tan(iz) to compute via tan(z).
Complex tan = Tan(new Complex(-value._imaginary, value._real));
return new Complex(tan._imaginary, -tan._real);
}
public static Complex Atan(Complex value)
@@ -286,6 +378,124 @@ namespace System.Numerics
return (ImaginaryOne / two) * (Log(One - ImaginaryOne * value) - Log(One + ImaginaryOne * value));
}
private static void Asin_Internal (double x, double y, out double b, out double bPrime, out double v) {
// This method for the inverse complex sine (and cosine) is described in Hull, Fairgrieve,
// and Tang, "Implementing the Complex Arcsine and Arccosine Functions Using Exception Handling",
// ACM Transactions on Mathematical Software (1997)
// (https://www.researchgate.net/profile/Ping_Tang3/publication/220493330_Implementing_the_Complex_Arcsine_and_Arccosine_Functions_Using_Exception_Handling/links/55b244b208ae9289a085245d.pdf)
// First, the basics: start with sin(w) = (e^{iw} - e^{-iw}) / (2i) = z. Here z is the input
// and w is the output. To solve for w, define t = e^{i w} and multiply through by t to
// get the quadratic equation t^2 - 2 i z t - 1 = 0. The solution is t = i z + sqrt(1 - z^2), so
// w = arcsin(z) = - i log( i z + sqrt(1 - z^2) )
// Decompose z = x + i y, multiply out i z + sqrt(1 - z^2), use log(s) = |s| + i arg(s), and do a
// bunch of algebra to get the components of w = arcsin(z) = u + i v
// u = arcsin(beta) v = sign(y) log(alpha + sqrt(alpha^2 - 1))
// where
// alpha = (rho + sigma) / 2 beta = (rho - sigma) / 2
// rho = sqrt((x + 1)^2 + y^2) sigma = sqrt((x - 1)^2 + y^2)
// These formulas appear in DLMF section 4.23. (http://dlmf.nist.gov/4.23), along with the analogous
// arccos(w) = arccos(beta) - i sign(y) log(alpha + sqrt(alpha^2 - 1))
// So alpha and beta together give us arcsin(w) and arccos(w).
// As written, alpha is not susceptible to cancelation errors, but beta is. To avoid cancelation, note
// beta = (rho^2 - sigma^2) / (rho + sigma) / 2 = (2 x) / (rho + sigma) = x / alpha
// which is not subject to cancelation. Note alpha >= 1 and |beta| <= 1.
// For alpha ~ 1, the argument of the log is near unity, so we compute (alpha - 1) instead,
// write the argument as 1 + (alpha - 1) + sqrt((alpha - 1)(alpha + 1)), and use the log1p function
// to compute the log without loss of accuracy.
// For beta ~ 1, arccos does not accurately resolve small angles, so we compute the tangent of the angle
// instead.
// Hull, Fairgrieve, and Tang derive formulas for (alpha - 1) and beta' = tan(u) that do not suffer
// from cancelation in these cases.
// For simplicity, we assume all positive inputs and return all positive outputs. The caller should
// assign signs appropriate to the desired cut conventions. We return v directly since its magnitude
// is the same for both arcsin and arccos. Instead of u, we usually return beta and sometimes beta'.
// If beta' is not computed, it is set to -1; if it is computed, it should be used instead of beta
// to determine u. Compute u = arcsin(beta) or u = arctan(beta') for arcsin, u = arccos(beta)
// or arctan(1/beta') for arccos.
Debug.Assert((x >= 0.0) || double.IsNaN(x));
Debug.Assert((y >= 0.0) || double.IsNaN(y));
// For x or y large enough to overflow alpha^2, we can simplify our formulas and avoid overflow.
if ((x > s_asinOverflowThreshold) || (y > s_asinOverflowThreshold))
{
b = -1.0;
bPrime = x / y;
double small, big;
if (x < y)
{
small = x;
big = y;
}
else
{
small = y;
big = x;
}
double ratio = small / big;
v = s_log2 + Math.Log(big) + 0.5 * Log1P(ratio * ratio);
}
else
{
double r = Hypot((x + 1.0), y);
double s = Hypot((x - 1.0), y);
double a = (r + s) * 0.5;
b = x / a;
if (b > 0.75)
{
if (x <= 1.0)
{
double amx = (y * y / (r + (x + 1.0)) + (s + (1.0 - x))) * 0.5;
bPrime = x / Math.Sqrt((a + x) * amx);
}
else
{
// In this case, amx ~ y^2. Since we take the square root of amx, we should
// pull y out from under the square root so we don't lose its contribution
// when y^2 underflows.
double t = (1.0 / (r + (x + 1.0)) + 1.0 / (s + (x - 1.0))) * 0.5;
bPrime = x / y / Math.Sqrt((a + x) * t);
}
}
else
{
bPrime = -1.0;
}
if (a < 1.5)
{
if (x < 1.0)
{
// This is another case where our expression is proportional to y^2 and
// we take its square root, so again we pull out a factor of y from
// under the square root.
double t = (1.0 / (r + (x + 1.0)) + 1.0 / (s + (1.0 - x))) * 0.5;
double am1 = y * y * t;
v = Log1P(am1 + y * Math.Sqrt(t * (a + 1.0)));
}
else
{
double am1 = (y * y / (r + (x + 1.0)) + (s + (x - 1.0))) * 0.5;
v = Log1P(am1 + Math.Sqrt(am1 * (a + 1.0)));
}
}
else
{
// Because of the test above, we can be sure that a * a will not overflow.
v = Math.Log(a + Math.Sqrt((a - 1.0) * (a + 1.0)));
}
}
}
public static Complex Log(Complex value)
{
return new Complex(Math.Log(Abs(value)), Math.Atan2(value._imaginary, value._real));

View File

@@ -114,13 +114,13 @@ namespace System.Numerics
{
if (d != null && d.Length > 0)
{
d[0] = ~d[0] + 1;
d[0] = unchecked(~d[0] + 1);
int i = 1;
// first do complement and +1 as long as carry is needed
for (; d[i - 1] == 0 && i < d.Length; i++)
{
d[i] = ~d[i] + 1;
d[i] = unchecked(~d[i] + 1);
}
// now ones complement is sufficient
for (; i < d.Length; i++)
@@ -137,8 +137,11 @@ namespace System.Numerics
public static uint Abs(int a)
{
uint mask = (uint)(a >> 31);
return ((uint)a ^ mask) - mask;
unchecked
{
uint mask = (uint)(a >> 31);
return ((uint)a ^ mask) - mask;
}
}
public static uint CombineHash(uint u1, uint u2)
@@ -148,7 +151,7 @@ namespace System.Numerics
public static int CombineHash(int n1, int n2)
{
return (int)CombineHash((uint)n1, (uint)n2);
return unchecked((int)CombineHash((uint)n1, (uint)n2));
}
public static int CbitHighZero(uint u)

View File

@@ -1488,7 +1488,7 @@ namespace System.Numerics.Tests
Char result = 'C';
while (result == 'C')
{
result = (Char)random.Next();
result = unchecked((Char)random.Next());
for (int i = 0; i < digits.Length; i++)
{
if (result < 'A')

View File

@@ -367,7 +367,7 @@ namespace System.Numerics.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp | TargetFrameworkMonikers.NetcoreUwp)]
[SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp | TargetFrameworkMonikers.Uap)]
public static void IComparable_Invalid_net46()
{
IComparable_Invalid(null);

View File

@@ -32,7 +32,7 @@ namespace System.Numerics.Tests
case "u~":
return new BigInteger(Not(bytes1).ToArray());
case "uLog10":
factor = (int)BigInteger.Log(num1, 10);
factor = unchecked((int)BigInteger.Log(num1, 10));
if (factor > 100)
{
for (int i = 0; i < factor - 100; i++)
@@ -50,7 +50,7 @@ namespace System.Numerics.Tests
}
return ApproximateBigInteger(result);
case "uLog":
factor = (int)BigInteger.Log(num1, 10);
factor = unchecked((int)BigInteger.Log(num1, 10));
if (factor > 100)
{
for (int i = 0; i < factor - 100; i++)

View File

@@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using Xunit;
using Microsoft.Xunit.Performance;
using Xunit.Abstractions;
namespace System.Numerics.Tests
@@ -20,8 +21,7 @@ namespace System.Numerics.Tests
_output = output;
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 64)]
[InlineData(1000000, 256, 256)]
@@ -34,8 +34,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Add(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 64)]
[InlineData(1000000, 256, 256)]
@@ -48,8 +47,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Subtract(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 64)]
[InlineData(1000000, 256, 256)]
@@ -62,8 +60,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Multiply(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16)]
[InlineData(1000000, 64)]
[InlineData(1000000, 256)]
@@ -76,8 +73,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, bits, v => BigInteger.Multiply(v, v));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 16)]
[InlineData(1000000, 256, 128)]
@@ -90,8 +86,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Divide(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 16)]
[InlineData(1000000, 256, 128)]
@@ -104,8 +99,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Remainder(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(1000000, 16, 16)]
[InlineData(1000000, 64, 64)]
[InlineData(100000, 256, 256)]
@@ -118,8 +112,7 @@ namespace System.Numerics.Tests
RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.GreatestCommonDivisor(l, r));
}
[Theory]
[ActiveIssue("PerformanceTest")]
[Benchmark] //PerformanceTest
[InlineData(100000, 16, 16, 16)]
[InlineData(10000, 64, 64, 64)]
[InlineData(1000, 256, 256, 256)]

Some files were not shown because too many files have changed in this diff Show More