Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -0,0 +1,61 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
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
{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B} = {D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Numerics", "src\System.Runtime.Numerics.csproj", "{D2C99D27-0BEF-4319-ADB3-05CBEBA8F69B}"
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
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<IsNETCoreApp>true</IsNETCoreApp>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netcoreapp;
uap;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,227 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ------------------------------------------------------------------------------
// Changes to this file must follow the http://aka.ms/api-review process.
// ------------------------------------------------------------------------------
namespace System.Numerics
{
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct BigInteger : System.IComparable, System.IComparable<System.Numerics.BigInteger>, System.IEquatable<System.Numerics.BigInteger>, System.IFormattable
{
[System.CLSCompliantAttribute(false)]
public BigInteger(byte[] value) { throw null; }
public BigInteger(decimal value) { throw null; }
public BigInteger(double value) { throw null; }
public BigInteger(int value) { throw null; }
public BigInteger(long value) { throw null; }
public BigInteger(float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public BigInteger(uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public BigInteger(ulong value) { throw null; }
public bool IsEven { get { throw null; } }
public bool IsOne { get { throw null; } }
public bool IsPowerOfTwo { get { throw null; } }
public bool IsZero { get { throw null; } }
public static System.Numerics.BigInteger MinusOne { get { throw null; } }
public static System.Numerics.BigInteger One { get { throw null; } }
public int Sign { get { throw null; } }
public static System.Numerics.BigInteger Zero { get { throw null; } }
public static System.Numerics.BigInteger Abs(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger Add(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static int Compare(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public int CompareTo(long other) { throw null; }
public int CompareTo(object obj) { throw null; }
public int CompareTo(System.Numerics.BigInteger other) { throw null; }
[System.CLSCompliantAttribute(false)]
public int CompareTo(ulong other) { throw null; }
public static System.Numerics.BigInteger Divide(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor) { throw null; }
public static System.Numerics.BigInteger DivRem(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor, out System.Numerics.BigInteger remainder) { throw null; }
public bool Equals(long other) { throw null; }
public bool Equals(System.Numerics.BigInteger other) { throw null; }
public override bool Equals(object obj) { throw null; }
[System.CLSCompliantAttribute(false)]
public bool Equals(ulong other) { throw null; }
public override int GetHashCode() { throw null; }
public static System.Numerics.BigInteger GreatestCommonDivisor(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static double Log(System.Numerics.BigInteger value) { throw null; }
public static double Log(System.Numerics.BigInteger value, double baseValue) { throw null; }
public static double Log10(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger Max(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger Min(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger ModPow(System.Numerics.BigInteger value, System.Numerics.BigInteger exponent, System.Numerics.BigInteger modulus) { throw null; }
public static System.Numerics.BigInteger Multiply(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger Negate(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger operator +(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator &(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator |(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator --(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger operator /(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor) { throw null; }
public static bool operator ==(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator ==(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator ==(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator ==(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator ==(ulong left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator ^(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static explicit operator System.Numerics.BigInteger(decimal value) { throw null; }
public static explicit operator System.Numerics.BigInteger(double value) { throw null; }
public static explicit operator byte (System.Numerics.BigInteger value) { throw null; }
public static explicit operator decimal (System.Numerics.BigInteger value) { throw null; }
public static explicit operator double (System.Numerics.BigInteger value) { throw null; }
public static explicit operator short (System.Numerics.BigInteger value) { throw null; }
public static explicit operator int (System.Numerics.BigInteger value) { throw null; }
public static explicit operator long (System.Numerics.BigInteger value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static explicit operator sbyte (System.Numerics.BigInteger value) { throw null; }
public static explicit operator float (System.Numerics.BigInteger value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static explicit operator ushort (System.Numerics.BigInteger value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static explicit operator uint (System.Numerics.BigInteger value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static explicit operator ulong (System.Numerics.BigInteger value) { throw null; }
public static explicit operator System.Numerics.BigInteger(float value) { throw null; }
public static bool operator >(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator >(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator >(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator >(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator >(ulong left, System.Numerics.BigInteger right) { throw null; }
public static bool operator >=(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator >=(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator >=(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator >=(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator >=(ulong left, System.Numerics.BigInteger right) { throw null; }
public static implicit operator System.Numerics.BigInteger(byte value) { throw null; }
public static implicit operator System.Numerics.BigInteger(short value) { throw null; }
public static implicit operator System.Numerics.BigInteger(int value) { throw null; }
public static implicit operator System.Numerics.BigInteger(long value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.BigInteger(sbyte value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.BigInteger(ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.BigInteger(uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.BigInteger(ulong value) { throw null; }
public static System.Numerics.BigInteger operator ++(System.Numerics.BigInteger value) { throw null; }
public static bool operator !=(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator !=(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator !=(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator !=(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator !=(ulong left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator <<(System.Numerics.BigInteger value, int shift) { throw null; }
public static bool operator <(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator <(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator <(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator <(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator <(ulong left, System.Numerics.BigInteger right) { throw null; }
public static bool operator <=(long left, System.Numerics.BigInteger right) { throw null; }
public static bool operator <=(System.Numerics.BigInteger left, long right) { throw null; }
public static bool operator <=(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator <=(System.Numerics.BigInteger left, ulong right) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool operator <=(ulong left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator %(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor) { throw null; }
public static System.Numerics.BigInteger operator *(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator ~(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger operator >>(System.Numerics.BigInteger value, int shift) { throw null; }
public static System.Numerics.BigInteger operator -(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public static System.Numerics.BigInteger operator -(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger operator +(System.Numerics.BigInteger value) { throw null; }
public static System.Numerics.BigInteger Parse(string value) { throw null; }
public static System.Numerics.BigInteger Parse(string value, System.Globalization.NumberStyles style) { throw null; }
public static System.Numerics.BigInteger Parse(string value, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
public static System.Numerics.BigInteger Parse(string value, System.IFormatProvider provider) { throw null; }
public static System.Numerics.BigInteger Pow(System.Numerics.BigInteger value, int exponent) { throw null; }
public static System.Numerics.BigInteger Remainder(System.Numerics.BigInteger dividend, System.Numerics.BigInteger divisor) { throw null; }
public static System.Numerics.BigInteger Subtract(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
public byte[] ToByteArray() { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider provider) { throw null; }
public string ToString(string format) { throw null; }
public string ToString(string format, System.IFormatProvider provider) { throw null; }
public static bool TryParse(string value, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Numerics.BigInteger result) { throw null; }
public static bool TryParse(string value, out System.Numerics.BigInteger result) { throw null; }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct Complex : System.IEquatable<System.Numerics.Complex>, System.IFormattable
{
public static readonly System.Numerics.Complex ImaginaryOne;
public static readonly System.Numerics.Complex One;
public static readonly System.Numerics.Complex Zero;
public Complex(double real, double imaginary) { throw null; }
public double Imaginary { get { throw null; } }
public double Magnitude { get { throw null; } }
public double Phase { get { throw null; } }
public double Real { get { throw null; } }
public static double Abs(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Acos(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Add(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Asin(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Atan(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Conjugate(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Cos(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Cosh(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Divide(System.Numerics.Complex dividend, System.Numerics.Complex divisor) { throw null; }
public bool Equals(System.Numerics.Complex value) { throw null; }
public override bool Equals(object obj) { throw null; }
public static System.Numerics.Complex Exp(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex FromPolarCoordinates(double magnitude, double phase) { throw null; }
public override int GetHashCode() { throw null; }
public static System.Numerics.Complex Log(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Log(System.Numerics.Complex value, double baseValue) { throw null; }
public static System.Numerics.Complex Log10(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Multiply(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Negate(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex operator +(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static bool operator ==(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static explicit operator System.Numerics.Complex(decimal value) { throw null; }
public static explicit operator System.Numerics.Complex(System.Numerics.BigInteger value) { throw null; }
public static implicit operator System.Numerics.Complex(byte value) { throw null; }
public static implicit operator System.Numerics.Complex(double value) { throw null; }
public static implicit operator System.Numerics.Complex(short value) { throw null; }
public static implicit operator System.Numerics.Complex(int value) { throw null; }
public static implicit operator System.Numerics.Complex(long value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.Complex(sbyte value) { throw null; }
public static implicit operator System.Numerics.Complex(float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.Complex(ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.Complex(uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Numerics.Complex(ulong value) { throw null; }
public static bool operator !=(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator *(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator -(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Pow(System.Numerics.Complex value, double power) { throw null; }
public static System.Numerics.Complex Pow(System.Numerics.Complex value, System.Numerics.Complex power) { throw null; }
public static System.Numerics.Complex Reciprocal(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Sin(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Sinh(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Sqrt(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Subtract(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Tan(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Tanh(System.Numerics.Complex value) { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider provider) { throw null; }
public string ToString(string format) { throw null; }
public string ToString(string format, System.IFormatProvider provider) { throw null; }
}
}

View File

@@ -0,0 +1,15 @@
<?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 Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="System.Runtime.Numerics.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
net463-Windows_NT;
netcoreapp;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,162 @@
<?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">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Argument_BadFormatSpecifier" xml:space="preserve">
<value>Format specifier was invalid.</value>
</data>
<data name="Argument_InvalidNumberStyles" xml:space="preserve">
<value>An undefined NumberStyles value is being used.</value>
</data>
<data name="Argument_InvalidHexStyle" xml:space="preserve">
<value>With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber.</value>
</data>
<data name="Argument_MustBeBigInt" xml:space="preserve">
<value>The parameter must be a BigInteger.</value>
</data>
<data name="Format_TooLarge" xml:space="preserve">
<value>The value is too large to be represented by this format specifier.</value>
</data>
<data name="ArgumentOutOfRange_MustBeNonNeg" xml:space="preserve">
<value>The number must be greater than or equal to zero.</value>
</data>
<data name="Overflow_BigIntInfinity" xml:space="preserve">
<value>BigInteger cannot represent infinity.</value>
</data>
<data name="Overflow_NotANumber" xml:space="preserve">
<value>The value is not a number.</value>
</data>
<data name="Overflow_ParseBigInteger" xml:space="preserve">
<value>The value could not be parsed.</value>
</data>
<data name="Overflow_Int32" xml:space="preserve">
<value>Value was either too large or too small for an Int32.</value>
</data>
<data name="Overflow_Int64" xml:space="preserve">
<value>Value was either too large or too small for an Int64.</value>
</data>
<data name="Overflow_UInt32" xml:space="preserve">
<value>Value was either too large or too small for a UInt32.</value>
</data>
<data name="Overflow_UInt64" xml:space="preserve">
<value>Value was either too large or too small for a UInt64.</value>
</data>
<data name="Overflow_Decimal" xml:space="preserve">
<value>Value was either too large or too small for a Decimal.</value>
</data>
</root>

View File

@@ -0,0 +1,49 @@
<?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>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>System.Numerics</RootNamespace>
<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'">
<Compile Include="System\Numerics\BigIntegerCalculator.AddSub.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.BitsBuffer.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.DivRem.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.FastReducer.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.GcdInv.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.PowMod.cs" />
<Compile Include="System\Numerics\BigIntegerCalculator.SquMul.cs" />
<Compile Include="System\Numerics\BigInteger.cs" />
<Compile Include="System\Numerics\BigNumber.cs" />
<Compile Include="System\Numerics\NumericsHelpers.cs" />
<Compile Include="System\Numerics\Complex.cs" />
<Compile Include="System\Globalization\FormatProvider.BigInteger.cs" />
<Compile Include="System\Globalization\FormatProvider.NumberBuffer.cs" />
<Compile Include="$(CommonPath)\System\Globalization\FormatProvider.Number.cs">
<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" />
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.Resources.ResourceManager" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Extensions" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -0,0 +1,73 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Security;
using System.Text;
namespace System.Globalization
{
internal partial class FormatProvider
{
[SecurityCritical]
internal static string FormatBigInteger(int precision, int scale, bool sign, string format, NumberFormatInfo numberFormatInfo, char[] digits, int startIndex)
{
unsafe
{
int maxDigits;
char fmt = Number.ParseFormatSpecifier(format, out maxDigits);
fixed (char* overrideDigits = digits)
{
FormatProvider.Number.NumberBuffer numberBuffer = new FormatProvider.Number.NumberBuffer();
numberBuffer.overrideDigits = overrideDigits + startIndex;
numberBuffer.precision = precision;
numberBuffer.scale = scale;
numberBuffer.sign = sign;
if (fmt != 0)
return Number.NumberToString(numberBuffer, fmt, maxDigits, numberFormatInfo, isDecimal: false);
return Number.NumberToStringFormat(numberBuffer, format, numberFormatInfo);
}
}
}
[SecurityCritical]
internal static bool TryStringToBigInteger(
string s,
NumberStyles styles,
NumberFormatInfo numberFormatInfo,
StringBuilder receiver, // Receives the decimal digits
out int precision,
out int scale,
out bool sign
)
{
FormatProvider.Number.NumberBuffer numberBuffer = new FormatProvider.Number.NumberBuffer();
unsafe
{
// Note: because we passed a non-null StringBuilder (receiver) to TryStringToNumber, it streams the digits into
// that instead of numberBuffer.digits. This is quite important since numberBuffer.digits is a fixed-buffer size
// and BigNumbers can have an arbitrary number of digits.
//
// Just in case a bug is ever introduced into TryStringToNumber that violates this, set the pointer that numberBuffer.digits returns
// to something that will AV.
numberBuffer.overrideDigits = (char*)0x1;
}
if (!Number.TryStringToNumber(s, styles, ref numberBuffer, receiver, numberFormatInfo, parseDecimal: false))
{
precision = default(int);
scale = default(int);
sign = default(bool);
return false;
}
else
{
precision = numberBuffer.precision;
scale = numberBuffer.scale;
sign = numberBuffer.sign;
return true;
}
}
}
}

View File

@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using System.Security;
namespace System.Globalization
{
internal partial class FormatProvider
{
private partial class Number
{
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct NumberBuffer
{
public int precision;
public int scale;
public bool sign;
public char* digits
{
[SecurityCritical]
get
{
return overrideDigits;
}
}
[SecurityCritical]
public char* overrideDigits; // Used for BigNumber support which can't be limited to 32 characters.
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,284 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Security;
namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
public static uint[] Add(uint[] left, uint right)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 1);
// Executes the addition for one big and one 32-bit integer.
// Thus, we've similar code than below, but there is no loop for
// processing the 32-bit integer, since it's a single element.
uint[] bits = new uint[left.Length + 1];
long digit = (long)left[0] + right;
bits[0] = (uint)digit;
long carry = digit >> 32;
for (int i = 1; i < left.Length; i++)
{
digit = left[i] + carry;
bits[i] = (uint)digit;
carry = digit >> 32;
}
bits[left.Length] = (uint)carry;
return bits;
}
[SecuritySafeCritical]
public static unsafe uint[] Add(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= right.Length);
// Switching to unsafe pointers helps sparing
// some nasty index calculations...
uint[] bits = new uint[left.Length + 1];
fixed (uint* l = left, r = right, b = bits)
{
Add(l, left.Length,
r, right.Length,
b, bits.Length);
}
return bits;
}
[SecuritySafeCritical]
private static unsafe void Add(uint* left, int leftLength,
uint* right, int rightLength,
uint* bits, int bitsLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(bitsLength == leftLength + 1);
// Executes the "grammar-school" algorithm for computing z = a + b.
// While calculating z_i = a_i + b_i we take care of overflow:
// Since a_i + b_i + c <= 2(2^32 - 1) + 1 = 2^33 - 1, our carry c
// has always the value 1 or 0; hence, we're safe here.
int i = 0;
long carry = 0L;
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) + right[i];
bits[i] = (uint)digit;
carry = digit >> 32;
}
for (; i < leftLength; i++)
{
long digit = left[i] + carry;
bits[i] = (uint)digit;
carry = digit >> 32;
}
bits[i] = (uint)carry;
}
[SecuritySafeCritical]
private static unsafe void AddSelf(uint* left, int leftLength,
uint* right, int rightLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
// Executes the "grammar-school" algorithm for computing z = a + b.
// Same as above, but we're writing the result directly to a and
// stop execution, if we're out of b and c is already 0.
int i = 0;
long carry = 0L;
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) + right[i];
left[i] = (uint)digit;
carry = digit >> 32;
}
for (; carry != 0 && i < leftLength; i++)
{
long digit = left[i] + carry;
left[i] = (uint)digit;
carry = digit >> 32;
}
Debug.Assert(carry == 0);
}
public static uint[] Subtract(uint[] left, uint right)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 1);
Debug.Assert(left[0] >= right || left.Length >= 2);
// Executes the subtraction for one big and one 32-bit integer.
// Thus, we've similar code than below, but there is no loop for
// processing the 32-bit integer, since it's a single element.
uint[] bits = new uint[left.Length];
long digit = (long)left[0] - right;
bits[0] = (uint)digit;
long carry = digit >> 32;
for (int i = 1; i < left.Length; i++)
{
digit = left[i] + carry;
bits[i] = (uint)digit;
carry = digit >> 32;
}
return bits;
}
[SecuritySafeCritical]
public static unsafe uint[] Subtract(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= right.Length);
Debug.Assert(Compare(left, right) >= 0);
// Switching to unsafe pointers helps sparing
// some nasty index calculations...
uint[] bits = new uint[left.Length];
fixed (uint* l = left, r = right, b = bits)
{
Subtract(l, left.Length,
r, right.Length,
b, bits.Length);
}
return bits;
}
[SecuritySafeCritical]
private static unsafe void Subtract(uint* left, int leftLength,
uint* right, int rightLength,
uint* bits, int bitsLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(Compare(left, leftLength, right, rightLength) >= 0);
Debug.Assert(bitsLength == leftLength);
// Executes the "grammar-school" algorithm for computing z = a - b.
// While calculating z_i = a_i - b_i we take care of overflow:
// Since a_i - b_i doesn't need any additional bit, our carry c
// has always the value -1 or 0; hence, we're safe here.
int i = 0;
long carry = 0L;
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) - right[i];
bits[i] = (uint)digit;
carry = digit >> 32;
}
for (; i < leftLength; i++)
{
long digit = left[i] + carry;
bits[i] = (uint)digit;
carry = digit >> 32;
}
Debug.Assert(carry == 0);
}
[SecuritySafeCritical]
private static unsafe void SubtractSelf(uint* left, int leftLength,
uint* right, int rightLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(Compare(left, leftLength, right, rightLength) >= 0);
// Executes the "grammar-school" algorithm for computing z = a - b.
// Same as above, but we're writing the result directly to a and
// stop execution, if we're out of b and c is already 0.
int i = 0;
long carry = 0L;
for (; i < rightLength; i++)
{
long digit = (left[i] + carry) - right[i];
left[i] = (uint)digit;
carry = digit >> 32;
}
for (; carry != 0 && i < leftLength; i++)
{
long digit = left[i] + carry;
left[i] = (uint)digit;
carry = digit >> 32;
}
Debug.Assert(carry == 0);
}
public static int Compare(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
if (left.Length < right.Length)
return -1;
if (left.Length > right.Length)
return 1;
for (int i = left.Length - 1; i >= 0; i--)
{
if (left[i] < right[i])
return -1;
if (left[i] > right[i])
return 1;
}
return 0;
}
[SecuritySafeCritical]
private static unsafe int Compare(uint* left, int leftLength,
uint* right, int rightLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
if (leftLength < rightLength)
return -1;
if (leftLength > rightLength)
return 1;
for (int i = leftLength - 1; i >= 0; i--)
{
if (left[i] < right[i])
return -1;
if (left[i] > right[i])
return 1;
}
return 0;
}
}
}

View File

@@ -0,0 +1,214 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Security;
namespace System.Numerics
{
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>
internal struct BitsBuffer
{
private uint[] _bits;
private int _length;
public BitsBuffer(int size, uint value)
{
Debug.Assert(size >= 1);
_bits = new uint[size];
_length = value != 0 ? 1 : 0;
_bits[0] = value;
}
public BitsBuffer(int size, uint[] value)
{
Debug.Assert(value != null);
Debug.Assert(size >= ActualLength(value));
_bits = new uint[size];
_length = ActualLength(value);
Array.Copy(value, 0, _bits, 0, _length);
}
[SecuritySafeCritical]
public unsafe void MultiplySelf(ref BitsBuffer value,
ref BitsBuffer temp)
{
Debug.Assert(temp._length == 0);
Debug.Assert(_length + value._length <= temp._bits.Length);
// Executes a multiplication for this and value, writes the
// result to temp. Switches this and temp arrays afterwards.
fixed (uint* b = _bits, v = value._bits, t = temp._bits)
{
if (_length < value._length)
{
Multiply(v, value._length,
b, _length,
t, _length + value._length);
}
else
{
Multiply(b, _length,
v, value._length,
t, _length + value._length);
}
}
Apply(ref temp, _length + value._length);
}
[SecuritySafeCritical]
public unsafe void SquareSelf(ref BitsBuffer temp)
{
Debug.Assert(temp._length == 0);
Debug.Assert(_length + _length <= temp._bits.Length);
// Executes a square for this, writes the result to temp.
// Switches this and temp arrays afterwards.
fixed (uint* b = _bits, t = temp._bits)
{
Square(b, _length,
t, _length + _length);
}
Apply(ref temp, _length + _length);
}
public void Reduce(ref FastReducer reducer)
{
// Executes a modulo operation using an optimized reducer.
// Thus, no need of any switching here, happens in-line.
_length = reducer.Reduce(_bits, _length);
}
[SecuritySafeCritical]
public unsafe void Reduce(uint[] modulus)
{
Debug.Assert(modulus != null);
// 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)
{
Divide(b, _length,
m, modulus.Length,
null, 0);
}
_length = ActualLength(_bits, modulus.Length);
}
}
[SecuritySafeCritical]
public unsafe void Reduce(ref BitsBuffer modulus)
{
// 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)
{
Divide(b, _length,
m, modulus._length,
null, 0);
}
_length = ActualLength(_bits, modulus._length);
}
}
public void Overwrite(ulong value)
{
Debug.Assert(_bits.Length >= 2);
if (_length > 2)
{
// Ensure leading zeros
Array.Clear(_bits, 2, _length - 2);
}
uint lo = (uint)value;
uint hi = (uint)(value >> 32);
_bits[0] = lo;
_bits[1] = hi;
_length = hi != 0 ? 2 : lo != 0 ? 1 : 0;
}
public void Overwrite(uint value)
{
Debug.Assert(_bits.Length >= 1);
if (_length > 1)
{
// Ensure leading zeros
Array.Clear(_bits, 1, _length - 1);
}
_bits[0] = value;
_length = value != 0 ? 1 : 0;
}
public uint[] GetBits()
{
return _bits;
}
public int GetSize()
{
return _bits.Length;
}
public int GetLength()
{
return _length;
}
public void Refresh(int maxLength)
{
Debug.Assert(_bits.Length >= maxLength);
if (_length > maxLength)
{
// Ensure leading zeros
Array.Clear(_bits, maxLength, _length - maxLength);
}
_length = ActualLength(_bits, maxLength);
}
private void Apply(ref BitsBuffer temp, int maxLength)
{
Debug.Assert(temp._length == 0);
Debug.Assert(maxLength <= temp._bits.Length);
// 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;
temp._bits = _bits;
_bits = t;
_length = ActualLength(_bits, maxLength);
}
}
}
}

View File

@@ -0,0 +1,359 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Security;
namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
public static uint[] Divide(uint[] left, uint right,
out uint remainder)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 1);
// Executes the division for one big and one 32-bit integer.
// Thus, we've similar code than below, but there is no loop for
// processing the 32-bit integer, since it's a single element.
uint[] quotient = new uint[left.Length];
ulong carry = 0UL;
for (int i = left.Length - 1; i >= 0; i--)
{
ulong value = (carry << 32) | left[i];
ulong digit = value / right;
quotient[i] = (uint)digit;
carry = value - digit * right;
}
remainder = (uint)carry;
return quotient;
}
public static uint[] Divide(uint[] left, uint right)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 1);
// Same as above, but only computing the quotient.
uint[] quotient = new uint[left.Length];
ulong carry = 0UL;
for (int i = left.Length - 1; i >= 0; i--)
{
ulong value = (carry << 32) | left[i];
ulong digit = value / right;
quotient[i] = (uint)digit;
carry = value - digit * right;
}
return quotient;
}
public static uint Remainder(uint[] left, uint right)
{
Debug.Assert(left != null);
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--)
{
ulong value = (carry << 32) | left[i];
carry = value % right;
}
return (uint)carry;
}
[SecuritySafeCritical]
public static unsafe uint[] Divide(uint[] left, uint[] right,
out uint[] remainder)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= 1);
Debug.Assert(right.Length >= 1);
Debug.Assert(left.Length >= right.Length);
// Switching to unsafe pointers helps sparing
// some nasty index calculations...
// 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)
{
Divide(l, localLeft.Length,
r, right.Length,
b, bits.Length);
}
remainder = localLeft;
return bits;
}
[SecuritySafeCritical]
public static unsafe uint[] Divide(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= 1);
Debug.Assert(right.Length >= 1);
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)
{
Divide(l, localLeft.Length,
r, right.Length,
b, bits.Length);
}
return bits;
}
[SecuritySafeCritical]
public static unsafe uint[] Remainder(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= 1);
Debug.Assert(right.Length >= 1);
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)
{
Divide(l, localLeft.Length,
r, right.Length,
null, 0);
}
return localLeft;
}
[SecuritySafeCritical]
private static unsafe void Divide(uint* left, int leftLength,
uint* right, int rightLength,
uint* bits, int bitsLength)
{
Debug.Assert(leftLength >= 1);
Debug.Assert(rightLength >= 1);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(bitsLength == leftLength - rightLength + 1
|| bitsLength == 0);
// Executes the "grammar-school" algorithm for computing q = a / b.
// Before calculating q_i, we get more bits into the highest bit
// block of the divisor. Thus, guessing digits of the quotient
// will be more precise. Additionally we'll get r = a % b.
uint divHi = right[rightLength - 1];
uint divLo = rightLength > 1 ? right[rightLength - 2] : 0;
// We measure the leading zeros of the divisor
int shift = LeadingZeros(divHi);
int backShift = 32 - shift;
// And, we make sure the most significant bit is set
if (shift > 0)
{
uint divNx = rightLength > 2 ? right[rightLength - 3] : 0;
divHi = (divHi << shift) | (divLo >> backShift);
divLo = (divLo << shift) | (divNx >> backShift);
}
// Then, we divide all of the bits as we would do it using
// pen and paper: guessing the next digit, subtracting, ...
for (int i = leftLength; i >= rightLength; i--)
{
int n = i - rightLength;
uint t = i < leftLength ? left[i] : 0;
ulong valHi = ((ulong)t << 32) | left[i - 1];
uint valLo = i > 1 ? left[i - 2] : 0;
// We shifted the divisor, we shift the dividend too
if (shift > 0)
{
uint valNx = i > 2 ? left[i - 3] : 0;
valHi = (valHi << shift) | (valLo >> backShift);
valLo = (valLo << shift) | (valNx >> backShift);
}
// First guess for the current digit of the quotient,
// which naturally must have only 32 bits...
ulong digit = valHi / divHi;
if (digit > 0xFFFFFFFF)
digit = 0xFFFFFFFF;
// Our first guess may be a little bit to big
while (DivideGuessTooBig(digit, valHi, valLo, divHi, divLo))
--digit;
if (digit > 0)
{
// Now it's time to subtract our current quotient
uint carry = SubtractDivisor(left + n, leftLength - n,
right, rightLength, digit);
if (carry != t)
{
Debug.Assert(carry == t + 1);
// Our guess was still exactly one too high
carry = AddDivisor(left + n, leftLength - n,
right, rightLength);
--digit;
Debug.Assert(carry == 1);
}
}
// We have the digit!
if (bitsLength != 0)
bits[n] = (uint)digit;
if (i < leftLength)
left[i] = 0;
}
}
[SecuritySafeCritical]
private static unsafe uint AddDivisor(uint* left, int leftLength,
uint* right, int rightLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
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;
carry = digit >> 32;
}
return (uint)carry;
}
[SecuritySafeCritical]
private static unsafe uint SubtractDivisor(uint* left, int leftLength,
uint* right, int rightLength,
ulong q)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(q <= 0xFFFFFFFF);
// Combines a subtract and a multiply operation, which is naturally
// more efficient than multiplying and then subtracting...
ulong carry = 0UL;
for (int i = 0; i < rightLength; i++)
{
carry += right[i] * q;
uint digit = (uint)carry;
carry = carry >> 32;
if (left[i] < digit)
++carry;
left[i] -= digit;
}
return (uint)carry;
}
private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo,
uint divHi, uint divLo)
{
Debug.Assert(q <= 0xFFFFFFFF);
// We multiply the two most significant limbs of the divisor
// with the current guess for the quotient. If those are bigger
// than the three most significant limbs of the current dividend
// we return true, which means the current guess is still too big.
ulong chkHi = divHi * q;
ulong chkLo = divLo * q;
chkHi = chkHi + (chkLo >> 32);
chkLo = chkLo & 0xFFFFFFFF;
if (chkHi < valHi)
return false;
if (chkHi > valHi)
return true;
if (chkLo < valLo)
return false;
if (chkLo > valLo)
return true;
return false;
}
private static uint[] CreateCopy(uint[] value)
{
Debug.Assert(value != null);
Debug.Assert(value.Length != 0);
uint[] bits = new uint[value.Length];
Array.Copy(value, 0, bits, 0, bits.Length);
return bits;
}
private static int LeadingZeros(uint value)
{
if (value == 0)
return 32;
int count = 0;
if ((value & 0xFFFF0000) == 0)
{
count += 16;
value = value << 16;
}
if ((value & 0xFF000000) == 0)
{
count += 8;
value = value << 8;
}
if ((value & 0xF0000000) == 0)
{
count += 4;
value = value << 4;
}
if ((value & 0xC0000000) == 0)
{
count += 2;
value = value << 2;
}
if ((value & 0x80000000) == 0)
{
count += 1;
}
return count;
}
}
}

View File

@@ -0,0 +1,152 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Security;
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>
internal struct FastReducer
{
private readonly uint[] _modulus;
private readonly uint[] _mu;
private readonly uint[] _q1;
private readonly uint[] _q2;
private readonly int _muLength;
public FastReducer(uint[] modulus)
{
Debug.Assert(modulus != null);
// Let r = 4^k, with 2^k > m
uint[] r = new uint[modulus.Length * 2 + 1];
r[r.Length - 1] = 1;
// Let mu = 4^k / m
_mu = Divide(r, modulus);
_modulus = modulus;
// Allocate memory for quotients once
_q1 = new uint[modulus.Length * 2 + 2];
_q2 = new uint[modulus.Length * 2 + 1];
_muLength = ActualLength(_mu);
}
public int Reduce(uint[] value, int length)
{
Debug.Assert(value != null);
Debug.Assert(length <= value.Length);
Debug.Assert(value.Length <= _modulus.Length * 2);
// Trivial: value is shorter
if (length < _modulus.Length)
return length;
// Let q1 = v/2^(k-1) * mu
int l1 = DivMul(value, length, _mu, _muLength,
_q1, _modulus.Length - 1);
// Let q2 = q1/2^(k+1) * m
int l2 = DivMul(_q1, l1, _modulus, _modulus.Length,
_q2, _modulus.Length + 1);
// Let v = (v - q2) % 2^(k+1) - i*m
return SubMod(value, length, _q2, l2,
_modulus, _modulus.Length + 1);
}
[SecuritySafeCritical]
private static unsafe int DivMul(uint[] left, int leftLength,
uint[] right, int rightLength,
uint[] bits, int k)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= leftLength);
Debug.Assert(right != null);
Debug.Assert(right.Length >= rightLength);
Debug.Assert(bits != null);
Debug.Assert(bits.Length + k >= leftLength + rightLength);
// Executes the multiplication algorithm for left and right,
// but skips the first k limbs of left, which is equivalent to
// preceding division by 2^(32*k). To spare memory allocations
// we write the result to an already allocated memory.
Array.Clear(bits, 0, bits.Length);
if (leftLength > k)
{
leftLength -= k;
fixed (uint* l = left, r = right, b = bits)
{
if (leftLength < rightLength)
{
Multiply(r, rightLength,
l + k, leftLength,
b, leftLength + rightLength);
}
else
{
Multiply(l + k, leftLength,
r, rightLength,
b, leftLength + rightLength);
}
}
return ActualLength(bits, leftLength + rightLength);
}
return 0;
}
[SecuritySafeCritical]
private static unsafe int SubMod(uint[] left, int leftLength,
uint[] right, int rightLength,
uint[] modulus, int k)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= leftLength);
Debug.Assert(right != null);
Debug.Assert(right.Length >= rightLength);
// Executes the subtraction algorithm for left and right,
// but considers only the first k limbs, which is equivalent to
// preceding reduction by 2^(32*k). Furthermore, if left is
// still greater than modulus, further subtractions are used.
if (leftLength > k)
leftLength = k;
if (rightLength > k)
rightLength = k;
fixed (uint* l = left, r = right, m = modulus)
{
SubtractSelf(l, leftLength, r, rightLength);
leftLength = ActualLength(left, leftLength);
while (Compare(l, leftLength, m, modulus.Length) >= 0)
{
SubtractSelf(l, leftLength, m, modulus.Length);
leftLength = ActualLength(left, leftLength);
}
}
Array.Clear(left, leftLength, left.Length - leftLength);
return leftLength;
}
}
}
}

View File

@@ -0,0 +1,280 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
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;
left = right;
right = temp;
}
return left;
}
public static ulong Gcd(ulong left, ulong right)
{
// Same as above, but for 64-bit values.
while (right > 0xFFFFFFFF)
{
ulong temp = left % right;
left = right;
right = temp;
}
if (right != 0)
return Gcd((uint)right, (uint)(left % right));
return left;
}
public static uint Gcd(uint[] left, uint right)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 1);
Debug.Assert(right != 0);
// A common divisor cannot be greater than right;
// we compute the remainder and continue above...
uint temp = Remainder(left, right);
return Gcd(right, temp);
}
public static uint[] Gcd(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(left.Length >= 2);
Debug.Assert(right != null);
Debug.Assert(right.Length >= 2);
Debug.Assert(Compare(left, right) >= 0);
BitsBuffer leftBuffer = new BitsBuffer(left.Length, left);
BitsBuffer rightBuffer = new BitsBuffer(right.Length, right);
Gcd(ref leftBuffer, ref rightBuffer);
return leftBuffer.GetBits();
}
private static void Gcd(ref BitsBuffer left, ref BitsBuffer right)
{
Debug.Assert(left.GetLength() >= 2);
Debug.Assert(right.GetLength() >= 2);
Debug.Assert(left.GetLength() >= right.GetLength());
// Executes Lehmer's gcd algorithm, but uses the most
// significant bits to work with 64-bit (not 32-bit) values.
// Furthermore we're using an optimized version due to Jebelean.
// http://cacr.uwaterloo.ca/hac/about/chap14.pdf (see 14.4.2)
// ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1992/92-69.ps.gz
while (right.GetLength() > 2)
{
ulong x, y;
ExtractDigits(ref left, ref right, out x, out y);
uint a = 1U, b = 0U;
uint c = 0U, d = 1U;
int iteration = 0;
// Lehmer's guessing
while (y != 0)
{
ulong q, r, s, t;
// Odd iteration
q = x / y;
if (q > 0xFFFFFFFF)
break;
r = a + q * c;
s = b + q * d;
t = x - q * y;
if (r > 0x7FFFFFFF || s > 0x7FFFFFFF)
break;
if (t < s || t + r > y - c)
break;
a = (uint)r;
b = (uint)s;
x = t;
++iteration;
if (x == b)
break;
// Even iteration
q = y / x;
if (q > 0xFFFFFFFF)
break;
r = d + q * b;
s = c + q * a;
t = y - q * x;
if (r > 0x7FFFFFFF || s > 0x7FFFFFFF)
break;
if (t < s || t + r > x - b)
break;
d = (uint)r;
c = (uint)s;
y = t;
++iteration;
if (y == c)
break;
}
if (b == 0)
{
// Euclid's step
left.Reduce(ref right);
BitsBuffer temp = left;
left = right;
right = temp;
}
else
{
// Lehmer's step
LehmerCore(ref left, ref right, a, b, c, d);
if (iteration % 2 == 1)
{
// Ensure left is larger than right
BitsBuffer temp = left;
left = right;
right = temp;
}
}
}
if (right.GetLength() > 0)
{
// Euclid's step
left.Reduce(ref right);
uint[] xBits = right.GetBits();
uint[] yBits = left.GetBits();
ulong x = ((ulong)xBits[1] << 32) | xBits[0];
ulong y = ((ulong)yBits[1] << 32) | yBits[0];
left.Overwrite(Gcd(x, y));
right.Overwrite(0);
}
}
private static void ExtractDigits(ref BitsBuffer xBuffer,
ref BitsBuffer yBuffer,
out ulong x, out ulong y)
{
Debug.Assert(xBuffer.GetLength() >= 3);
Debug.Assert(yBuffer.GetLength() >= 3);
Debug.Assert(xBuffer.GetLength() >= yBuffer.GetLength());
// Extracts the most significant bits of x and y,
// but ensures the quotient x / y does not change!
uint[] xBits = xBuffer.GetBits();
int xLength = xBuffer.GetLength();
uint[] yBits = yBuffer.GetBits();
int yLength = yBuffer.GetLength();
ulong xh = xBits[xLength - 1];
ulong xm = xBits[xLength - 2];
ulong xl = xBits[xLength - 3];
ulong yh, ym, yl;
// arrange the bits
switch (xLength - yLength)
{
case 0:
yh = yBits[yLength - 1];
ym = yBits[yLength - 2];
yl = yBits[yLength - 3];
break;
case 1:
yh = 0UL;
ym = yBits[yLength - 1];
yl = yBits[yLength - 2];
break;
case 2:
yh = 0UL;
ym = 0UL;
yl = yBits[yLength - 1];
break;
default:
yh = 0UL;
ym = 0UL;
yl = 0UL;
break;
}
// Use all the bits but one, see [hac] 14.58 (ii)
int z = LeadingZeros((uint)xh);
x = ((xh << 32 + z) | (xm << z) | (xl >> 32 - z)) >> 1;
y = ((yh << 32 + z) | (ym << z) | (yl >> 32 - z)) >> 1;
Debug.Assert(x >= y);
}
private static void LehmerCore(ref BitsBuffer xBuffer,
ref BitsBuffer yBuffer,
long a, long b,
long c, long d)
{
Debug.Assert(xBuffer.GetLength() >= 1);
Debug.Assert(yBuffer.GetLength() >= 1);
Debug.Assert(xBuffer.GetLength() >= yBuffer.GetLength());
Debug.Assert(a <= 0x7FFFFFFF && b <= 0x7FFFFFFF);
Debug.Assert(c <= 0x7FFFFFFF && d <= 0x7FFFFFFF);
// Executes the combined calculation of Lehmer's step.
uint[] x = xBuffer.GetBits();
uint[] y = yBuffer.GetBits();
int length = yBuffer.GetLength();
long xCarry = 0L, yCarry = 0L;
for (int i = 0; i < length; i++)
{
long xDigit = a * x[i] - b * y[i] + xCarry;
long yDigit = d * y[i] - c * x[i] + yCarry;
xCarry = xDigit >> 32;
yCarry = yDigit >> 32;
x[i] = (uint)xDigit;
y[i] = (uint)yDigit;
}
xBuffer.Refresh(length);
yBuffer.Refresh(length);
}
}
}

View File

@@ -0,0 +1,383 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
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>
public static uint[] Pow(uint value, uint power)
{
// The basic pow method for a 32-bit integer.
// To spare memory allocations we first roughly
// estimate an upper bound for our buffers.
int size = PowBound(power, 1, 1);
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, ref v);
}
public static uint[] Pow(uint[] value, uint power)
{
Debug.Assert(value != null);
// 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);
}
private static uint[] PowCore(uint power, ref BitsBuffer value)
{
// Executes the basic pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
BitsBuffer result = new BitsBuffer(size, 1);
PowCore(power, ref value, ref result, ref temp);
return result.GetBits();
}
private static int PowBound(uint power, int valueLength,
int resultLength)
{
// The basic pow algorithm, but instead of squaring
// and multiplying we just sum up the lengths.
while (power != 0)
{
checked
{
if ((power & 1) == 1)
resultLength += valueLength;
if (power != 1)
valueLength += valueLength;
}
power = power >> 1;
}
return resultLength;
}
private static void PowCore(uint power, ref BitsBuffer value,
ref BitsBuffer result, ref BitsBuffer temp)
{
// The basic pow algorithm using square-and-multiply.
while (power != 0)
{
if ((power & 1) == 1)
result.MultiplySelf(ref value, ref temp);
if (power != 1)
value.SquareSelf(ref temp);
power = power >> 1;
}
}
public static uint Pow(uint value, uint power, uint modulus)
{
// The 32-bit modulus pow method for a 32-bit integer
// raised by a 32-bit integer...
return PowCore(power, modulus, value, 1);
}
public static uint Pow(uint[] value, uint power, uint modulus)
{
Debug.Assert(value != null);
// 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);
}
public static uint Pow(uint value, uint[] power, uint modulus)
{
Debug.Assert(power != null);
// The 32-bit modulus pow method for a 32-bit integer
// raised by a big integer...
return PowCore(power, modulus, value, 1);
}
public static uint Pow(uint[] value, uint[] power, uint modulus)
{
Debug.Assert(value != null);
Debug.Assert(power != null);
// 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);
}
private static uint PowCore(uint[] power, uint modulus,
ulong value, ulong result)
{
// 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];
for (int j = 0; j < 32; j++)
{
if ((p & 1) == 1)
result = (result * value) % modulus;
value = (value * value) % modulus;
p = p >> 1;
}
}
return PowCore(power[power.Length - 1], modulus, value, result);
}
private static uint PowCore(uint power, uint modulus,
ulong value, ulong result)
{
// 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)
result = (result * value) % modulus;
if (power != 1)
value = (value * value) % modulus;
power = power >> 1;
}
return (uint)(result % modulus);
}
public static uint[] Pow(uint value, uint power, uint[] modulus)
{
Debug.Assert(modulus != null);
// 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);
}
public static uint[] Pow(uint[] value, uint power, uint[] modulus)
{
Debug.Assert(value != null);
Debug.Assert(modulus != null);
// The big modulus pow method for a big integer
// raised by a 32-bit integer...
if (value.Length > modulus.Length)
value = Remainder(value, modulus);
int size = modulus.Length + modulus.Length;
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, modulus, ref v);
}
public static uint[] Pow(uint value, uint[] power, uint[] modulus)
{
Debug.Assert(power != null);
Debug.Assert(modulus != null);
// The big modulus pow method for a 32-bit integer
// raised by a big integer...
int size = modulus.Length + modulus.Length;
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, modulus, ref v);
}
public static uint[] Pow(uint[] value, uint[] power, uint[] modulus)
{
Debug.Assert(value != null);
Debug.Assert(power != null);
Debug.Assert(modulus != null);
// The big modulus pow method for a big integer
// raised by a big integer...
if (value.Length > modulus.Length)
value = Remainder(value, modulus);
int size = modulus.Length + modulus.Length;
BitsBuffer v = new BitsBuffer(size, value);
return PowCore(power, modulus, ref v);
}
// Mutable for unit testing...
private static int ReducerThreshold = 32;
private static uint[] PowCore(uint[] power, uint[] modulus,
ref BitsBuffer value)
{
// Executes the big pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
BitsBuffer result = new BitsBuffer(size, 1);
if (modulus.Length < ReducerThreshold)
{
PowCore(power, modulus, ref value, ref result, ref temp);
}
else
{
FastReducer reducer = new FastReducer(modulus);
PowCore(power, ref reducer, ref value, ref result, ref temp);
}
return result.GetBits();
}
private static uint[] PowCore(uint power, uint[] modulus,
ref BitsBuffer value)
{
// Executes the big pow algorithm.
int size = value.GetSize();
BitsBuffer temp = new BitsBuffer(size, 0);
BitsBuffer result = new BitsBuffer(size, 1);
if (modulus.Length < ReducerThreshold)
{
PowCore(power, modulus, ref value, ref result, ref temp);
}
else
{
FastReducer reducer = new FastReducer(modulus);
PowCore(power, ref reducer, ref value, ref result, ref temp);
}
return result.GetBits();
}
private static void PowCore(uint[] power, uint[] modulus,
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 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];
for (int j = 0; j < 32; j++)
{
if ((p & 1) == 1)
{
result.MultiplySelf(ref value, ref temp);
result.Reduce(modulus);
}
value.SquareSelf(ref temp);
value.Reduce(modulus);
p = p >> 1;
}
}
PowCore(power[power.Length - 1], modulus, ref value, ref result,
ref temp);
}
private static void PowCore(uint power, uint[] modulus,
ref BitsBuffer value, ref BitsBuffer result,
ref BitsBuffer temp)
{
// 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)
{
result.MultiplySelf(ref value, ref temp);
result.Reduce(modulus);
}
if (power != 1)
{
value.SquareSelf(ref temp);
value.Reduce(modulus);
}
power = power >> 1;
}
}
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];
for (int j = 0; j < 32; j++)
{
if ((p & 1) == 1)
{
result.MultiplySelf(ref value, ref temp);
result.Reduce(ref reducer);
}
value.SquareSelf(ref temp);
value.Reduce(ref reducer);
p = p >> 1;
}
}
PowCore(power[power.Length - 1], ref reducer, ref value, ref result,
ref 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 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)
{
result.MultiplySelf(ref value, ref temp);
result.Reduce(ref reducer);
}
if (power != 1)
{
value.SquareSelf(ref temp);
value.Reduce(ref reducer);
}
power = power >> 1;
}
}
private static int ActualLength(uint[] value)
{
// 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);
}
private static int ActualLength(uint[] value, int length)
{
Debug.Assert(value != null);
Debug.Assert(length <= value.Length);
while (length > 0 && value[length - 1] == 0)
--length;
return length;
}
}
}

View File

@@ -0,0 +1,402 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Security;
namespace System.Numerics
{
internal static partial class BigIntegerCalculator
{
[SecuritySafeCritical]
public static unsafe uint[] Square(uint[] value)
{
Debug.Assert(value != null);
// Switching to unsafe pointers helps sparing
// some nasty index calculations...
uint[] bits = new uint[value.Length + value.Length];
fixed (uint* v = value, b = bits)
{
Square(v, value.Length,
b, bits.Length);
}
return bits;
}
// Mutable for unit testing...
private static int SquareThreshold = 32;
private static int AllocationThreshold = 256;
[SecuritySafeCritical]
private static unsafe void Square(uint* value, int valueLength,
uint* bits, int bitsLength)
{
Debug.Assert(valueLength >= 0);
Debug.Assert(bitsLength == valueLength + valueLength);
// Executes different algorithms for computing z = a * a
// based on the actual length of a. If a is "small" enough
// we stick to the classic "grammar-school" method; for the
// rest we switch to implementations with less complexity
// albeit more overhead (which needs to pay off!).
// NOTE: useful thresholds needs some "empirical" testing,
// which are smaller in DEBUG mode for testing purpose.
if (valueLength < SquareThreshold)
{
// Squares the bits using the "grammar-school" method.
// Envisioning the "rhombus" of a pen-and-paper calculation
// we see that computing z_i+j += a_j * a_i can be optimized
// since a_j * a_i = a_i * a_j (we're squaring after all!).
// Thus, we directly get z_i+j += 2 * a_j * a_i + c.
// ATTENTION: an ordinary multiplication is safe, because
// z_i+j + a_j * a_i + c <= 2(2^32 - 1) + (2^32 - 1)^2 =
// = 2^64 - 1 (which perfectly matches with ulong!). But
// here we would need an UInt65... Hence, we split these
// operation and do some extra shifts.
for (int i = 0; i < valueLength; i++)
{
ulong carry = 0UL;
for (int j = 0; j < i; j++)
{
ulong digit1 = bits[i + j] + carry;
ulong digit2 = (ulong)value[j] * value[i];
bits[i + j] = (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 + 1] = (uint)(digits >> 32);
}
}
else
{
// Based on the Toom-Cook multiplication we split value
// into two smaller values, doing recursive squaring.
// The special form of this multiplication, where we
// split both operands into two operands, is also known
// as the Karatsuba algorithm...
// https://en.wikipedia.org/wiki/Toom-Cook_multiplication
// https://en.wikipedia.org/wiki/Karatsuba_algorithm
// Say we want to compute z = a * a ...
// ... we need to determine our new length (just the half)
int n = valueLength >> 1;
int n2 = n << 1;
// ... split value like a = (a_1 << n) + a_0
uint* valueLow = value;
int valueLowLength = n;
uint* valueHigh = value + n;
int valueHighLength = valueLength - n;
// ... prepare our result array (to reuse its memory)
uint* bitsLow = bits;
int bitsLowLength = n2;
uint* bitsHigh = bits + n2;
int bitsHighLength = bitsLength - n2;
// ... compute z_0 = a_0 * a_0 (squaring again!)
Square(valueLow, valueLowLength,
bitsLow, bitsLowLength);
// ... compute z_2 = a_1 * a_1 (squaring again!)
Square(valueHigh, valueHighLength,
bitsHigh, bitsHighLength);
int foldLength = valueHighLength + 1;
int coreLength = foldLength + foldLength;
if (coreLength < AllocationThreshold)
{
uint* fold = stackalloc uint[foldLength];
uint* core = stackalloc uint[coreLength];
// ... compute z_a = a_1 + a_0 (call it fold...)
Add(valueHigh, valueHighLength,
valueLow, valueLowLength,
fold, foldLength);
// ... compute z_1 = z_a * z_a - z_0 - z_2
Square(fold, foldLength,
core, coreLength);
SubtractCore(bitsHigh, bitsHighLength,
bitsLow, bitsLowLength,
core, coreLength);
// ... and finally merge the result! :-)
AddSelf(bits + n, bitsLength - n, core, coreLength);
}
else
{
fixed (uint* fold = new uint[foldLength],
core = new uint[coreLength])
{
// ... compute z_a = a_1 + a_0 (call it fold...)
Add(valueHigh, valueHighLength,
valueLow, valueLowLength,
fold, foldLength);
// ... compute z_1 = z_a * z_a - z_0 - z_2
Square(fold, foldLength,
core, coreLength);
SubtractCore(bitsHigh, bitsHighLength,
bitsLow, bitsLowLength,
core, coreLength);
// ... and finally merge the result! :-)
AddSelf(bits + n, bitsLength - n, core, coreLength);
}
}
}
}
public static uint[] Multiply(uint[] left, uint right)
{
Debug.Assert(left != null);
// Executes the multiplication for one big and one 32-bit integer.
// Since every step holds the already slightly familiar equation
// a_i * b + c <= 2^32 - 1 + (2^32 - 1)^2 < 2^64 - 1,
// we are safe regarding to overflows.
int i = 0;
ulong carry = 0UL;
uint[] bits = new uint[left.Length + 1];
for (; i < left.Length; i++)
{
ulong digits = (ulong)left[i] * right + carry;
bits[i] = (uint)digits;
carry = digits >> 32;
}
bits[i] = (uint)carry;
return bits;
}
[SecuritySafeCritical]
public static unsafe uint[] Multiply(uint[] left, uint[] right)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(left.Length >= right.Length);
// Switching to unsafe pointers helps sparing
// some nasty index calculations...
uint[] bits = new uint[left.Length + right.Length];
fixed (uint* l = left, r = right, b = bits)
{
Multiply(l, left.Length,
r, right.Length,
b, bits.Length);
}
return bits;
}
// Mutable for unit testing...
private static int MultiplyThreshold = 32;
[SecuritySafeCritical]
private static unsafe void Multiply(uint* left, int leftLength,
uint* right, int rightLength,
uint* bits, int bitsLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(bitsLength == leftLength + rightLength);
// Executes different algorithms for computing z = a * b
// based on the actual length of b. If b is "small" enough
// we stick to the classic "grammar-school" method; for the
// rest we switch to implementations with less complexity
// albeit more overhead (which needs to pay off!).
// NOTE: useful thresholds needs some "empirical" testing,
// which are smaller in DEBUG mode for testing purpose.
if (rightLength < MultiplyThreshold)
{
// Multiplies the bits using the "grammar-school" method.
// Envisioning the "rhombus" of a pen-and-paper calculation
// should help getting the idea of these two loops...
// The inner multiplication operations are safe, because
// z_i+j + a_j * b_i + c <= 2(2^32 - 1) + (2^32 - 1)^2 =
// = 2^64 - 1 (which perfectly matches with ulong!).
for (int i = 0; i < rightLength; i++)
{
ulong carry = 0UL;
for (int j = 0; j < leftLength; j++)
{
ulong digits = bits[i + j] + carry
+ (ulong)left[j] * right[i];
bits[i + j] = (uint)digits;
carry = digits >> 32;
}
bits[i + leftLength] = (uint)carry;
}
}
else
{
// Based on the Toom-Cook multiplication we split left/right
// into two smaller values, doing recursive multiplication.
// The special form of this multiplication, where we
// split both operands into two operands, is also known
// as the Karatsuba algorithm...
// https://en.wikipedia.org/wiki/Toom-Cook_multiplication
// https://en.wikipedia.org/wiki/Karatsuba_algorithm
// Say we want to compute z = a * b ...
// ... we need to determine our new length (just the half)
int n = rightLength >> 1;
int n2 = n << 1;
// ... split left like a = (a_1 << n) + a_0
uint* leftLow = left;
int leftLowLength = n;
uint* leftHigh = left + n;
int leftHighLength = leftLength - n;
// ... split right like b = (b_1 << n) + b_0
uint* rightLow = right;
int rightLowLength = n;
uint* rightHigh = right + n;
int rightHighLength = rightLength - n;
// ... prepare our result array (to reuse its memory)
uint* bitsLow = bits;
int bitsLowLength = n2;
uint* bitsHigh = bits + n2;
int bitsHighLength = bitsLength - n2;
// ... compute z_0 = a_0 * b_0 (multiply again)
Multiply(leftLow, leftLowLength,
rightLow, rightLowLength,
bitsLow, bitsLowLength);
// ... compute z_2 = a_1 * b_1 (multiply again)
Multiply(leftHigh, leftHighLength,
rightHigh, rightHighLength,
bitsHigh, bitsHighLength);
int leftFoldLength = leftHighLength + 1;
int rightFoldLength = rightHighLength + 1;
int coreLength = leftFoldLength + rightFoldLength;
if (coreLength < AllocationThreshold)
{
uint* leftFold = stackalloc uint[leftFoldLength];
uint* rightFold = stackalloc uint[rightFoldLength];
uint* core = stackalloc uint[coreLength];
// ... compute z_a = a_1 + a_0 (call it fold...)
Add(leftHigh, leftHighLength,
leftLow, leftLowLength,
leftFold, leftFoldLength);
// ... compute z_b = b_1 + b_0 (call it fold...)
Add(rightHigh, rightHighLength,
rightLow, rightLowLength,
rightFold, rightFoldLength);
// ... compute z_1 = z_a * z_b - z_0 - z_2
Multiply(leftFold, leftFoldLength,
rightFold, rightFoldLength,
core, coreLength);
SubtractCore(bitsHigh, bitsHighLength,
bitsLow, bitsLowLength,
core, coreLength);
// ... and finally merge the result! :-)
AddSelf(bits + n, bitsLength - n, core, coreLength);
}
else
{
fixed (uint* leftFold = new uint[leftFoldLength],
rightFold = new uint[rightFoldLength],
core = new uint[coreLength])
{
// ... compute z_a = a_1 + a_0 (call it fold...)
Add(leftHigh, leftHighLength,
leftLow, leftLowLength,
leftFold, leftFoldLength);
// ... compute z_b = b_1 + b_0 (call it fold...)
Add(rightHigh, rightHighLength,
rightLow, rightLowLength,
rightFold, rightFoldLength);
// ... compute z_1 = z_a * z_b - z_0 - z_2
Multiply(leftFold, leftFoldLength,
rightFold, rightFoldLength,
core, coreLength);
SubtractCore(bitsHigh, bitsHighLength,
bitsLow, bitsLowLength,
core, coreLength);
// ... and finally merge the result! :-)
AddSelf(bits + n, bitsLength - n, core, coreLength);
}
}
}
}
[SecuritySafeCritical]
private static unsafe void SubtractCore(uint* left, int leftLength,
uint* right, int rightLength,
uint* core, int coreLength)
{
Debug.Assert(leftLength >= 0);
Debug.Assert(rightLength >= 0);
Debug.Assert(coreLength >= 0);
Debug.Assert(leftLength >= rightLength);
Debug.Assert(coreLength >= leftLength);
// Executes a special subtraction algorithm for the multiplication,
// which needs to subtract two different values from a core value,
// while core is always bigger than the sum of these values.
// NOTE: we could do an ordinary subtraction of course, but we spare
// one "run", if we do this computation within a single one...
int i = 0;
long carry = 0L;
for (; i < rightLength; i++)
{
long digit = (core[i] + carry) - left[i] - right[i];
core[i] = (uint)digit;
carry = digit >> 32;
}
for (; i < leftLength; i++)
{
long digit = (core[i] + carry) - left[i];
core[i] = (uint)digit;
carry = digit >> 32;
}
for (; carry != 0 && i < coreLength; i++)
{
long digit = core[i] + carry;
core[i] = (uint)digit;
carry = digit >> 32;
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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