You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
61
external/corefx/src/System.Runtime.Numerics/System.Runtime.Numerics.sln
vendored
Normal file
61
external/corefx/src/System.Runtime.Numerics/System.Runtime.Numerics.sln
vendored
Normal 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
|
||||
8
external/corefx/src/System.Runtime.Numerics/dir.props
vendored
Normal file
8
external/corefx/src/System.Runtime.Numerics/dir.props
vendored
Normal 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>
|
||||
9
external/corefx/src/System.Runtime.Numerics/ref/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Runtime.Numerics/ref/Configurations.props
vendored
Normal 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>
|
||||
227
external/corefx/src/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
vendored
Normal file
227
external/corefx/src/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
vendored
Normal 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; }
|
||||
}
|
||||
}
|
||||
15
external/corefx/src/System.Runtime.Numerics/ref/System.Runtime.Numerics.csproj
vendored
Normal file
15
external/corefx/src/System.Runtime.Numerics/ref/System.Runtime.Numerics.csproj
vendored
Normal 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>
|
||||
9
external/corefx/src/System.Runtime.Numerics/src/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Runtime.Numerics/src/Configurations.props
vendored
Normal 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>
|
||||
162
external/corefx/src/System.Runtime.Numerics/src/Resources/Strings.resx
vendored
Normal file
162
external/corefx/src/System.Runtime.Numerics/src/Resources/Strings.resx
vendored
Normal 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>
|
||||
49
external/corefx/src/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj
vendored
Normal file
49
external/corefx/src/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj
vendored
Normal 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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2043
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
vendored
Normal file
2043
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
284
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.AddSub.cs
vendored
Normal file
284
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.AddSub.cs
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
214
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.BitsBuffer.cs
vendored
Normal file
214
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.BitsBuffer.cs
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
359
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
vendored
Normal file
359
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
152
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.FastReducer.cs
vendored
Normal file
152
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.FastReducer.cs
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
280
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.GcdInv.cs
vendored
Normal file
280
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.GcdInv.cs
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
383
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs
vendored
Normal file
383
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
402
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.SquMul.cs
vendored
Normal file
402
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.SquMul.cs
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
675
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigNumber.cs
vendored
Normal file
675
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/BigNumber.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
504
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/Complex.cs
vendored
Normal file
504
external/corefx/src/System.Runtime.Numerics/src/System/Numerics/Complex.cs
vendored
Normal file
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
Reference in New Issue
Block a user