Initial Commit

master
Harald Wolff 2021-03-18 19:38:09 +01:00
commit cdc8e0cc8d
12 changed files with 1381 additions and 0 deletions

40
.gitignore vendored 100644
View File

@ -0,0 +1,40 @@
# Autosave files
*~
# build
[Oo]bj/
[Bb]in/
packages/
TestResults/
# globs
Makefile.in
*.DS_Store
*.sln.cache
*.suo
*.cache
*.pidb
*.userprefs
*.usertasks
config.log
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.user
*.tar.gz
tarballs/
test-results/
Thumbs.db
# Mac bundle stuff
*.dmg
*.app
# resharper
*_Resharper.*
*.Resharper
# dotCover
*.dotCover

12
big.impl/Makefile 100644
View File

@ -0,0 +1,12 @@
OBJECTS=bigint.o
CFLAGS=-fPIC
all: distribute
distribute: ../ln.biginteger/libbigint.so
../ln.biginteger/libbigint.so: $(OBJECTS)
gcc -shared -o ../ln.biginteger/libbigint.so $(OBJECTS)

232
big.impl/bigint.c 100644
View File

@ -0,0 +1,232 @@
#include <stdint.h>
#include <string.h>
uint32_t one[] = { 1 };
int32_t max(int32_t a,int32_t b)
{
return a>b ? a : b;
}
int32_t big_get_length(uint32_t *op, int32_t length)
{
for (; length > 1; length--){
if (
((op[length-1] != 0) || ((op[length-2] & (1<<31))!=0)) && ((op[length-1] != 0xFFFFFFFF) || ((op[length-2] & (1<<31))==0))
){
break;
}
}
return length;
}
int32_t big_sign(uint32_t *op, int32_t length)
{
if ((length == 1) && (op[0] == 0))
return 0;
else if ((op[length-1] & 0x80000000) != 0)
return -1;
else
return 1;
}
int32_t big_log2(uint32_t *op, int32_t length)
{
if (big_sign(op, length) < 0)
{
for (int n = (length << 5)-1; n > 0; n--)
{
if ((op[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) == 0)
{
return 1 - n;
}
}
return 0;
} else {
for (int n = length << 5; n > 0; n--)
{
if ((op[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) != 0)
{
return n - 1;
}
}
return 0;
}
}
int32_t big_cmp(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
{
int l = max(length_a, length_b);
for (int n=l-1; n >= 0; n--)
{
int a = n < length_a ? op_a[n] : 0;
int b = n < length_b ? op_b[n] : 0;
if (a < b)
return -1;
else if (a > b)
return 1;
}
return 0;
}
void big_shl(uint32_t *op, int32_t length, int32_t n)
{
if (n > 0)
{
int step = n >> 5;
n &= 0x1F;
for (int i = length; i > 0; i--)
{
int b1 = i - 1 - step;
int b2 = b1 - 1;
if (b1 >= 0){
op[i - 1] = (op[b1] << n);
if ((n != 0)&&(b2 >= 0))
{
op[i - 1] |= ((op[b2] >> (32 - n)));
}
} else {
op[i - 1] = 0;
}
}
}
}
void big_shr(uint32_t *op, int32_t length, int32_t n)
{
if (n > 0)
{
int32_t s = big_sign(op, length);
int step = n >> 5;
n &= 0x1F;
for (int i = 0; i < length; i++)
{
int b1 = i + step;
int b2 = b1 + 1;
if (b1 < length)
{
op[i] = (op[b1] >> n);
if ((b2 == length) && (s)){
op[i] |= ((0xffffffff << (32 - n)));
} else if ((n != 0) && (b2 < length))
{
op[i] |= ((op[b2] << (32 - n)));
}
} else {
op[i] = s ? 0xFFFFFFFF : 0;
}
}
}
}
void big_add(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
{
uint64_t c = 0;
for (int n=0;n<length_a;n++)
{
c += op_a[n] + ((n < length_b) ? op_b[n] : 0);
op_a[n] = (c & 0xffffffff);
c >>= 32;
if ((c == 0) && (n > length_b))
break;
}
}
void big_sub(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
{
uint64_t c = 0;
for (int n=0;n<length_a;n++)
{
c += op_a[n] - ((n < length_b) ? op_b[n] : 0);
op_a[n] = (c & 0xffffffff);
c >>= 32;
if ((c == 0) && (n > length_b))
break;
}
}
void big_twos(uint32_t *op, int32_t length)
{
for (int n=0;n<length;n++)
op[n] = ~op[n];
big_add(op, length, one, 1);
}
void big_smul(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b, uint32_t* result)
{
int32_t l = length_a + length_b;
for (int l1 = 0; l1 < length_a; l1++)
{
for (int l2 = 0; l2 < length_b; l2++)
{
int target = l1 + l2;
uint64_t ui64 = ((uint64_t)op_a[l1] * op_b[l2]);
for (int ct = target; (ct < l) && (ui64 != 0); ct++)
{
ui64 += result[ct];
result[ct] = (uint32_t)ui64;
ui64 >>= 32;
}
}
}
}
void big_divmod(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
{
int sign_a = big_sign(op_a, length_a);
int sign_b = big_sign(op_b, length_b);
uint32_t dividend[length_a];
uint32_t divisor[length_a];
memset( divisor, 0x00, sizeof(divisor) );
memcpy( dividend, op_a, length_a << 2);
memcpy( divisor, op_b, length_b << 2);
memset( op_a, 0x00, length_a << 2);
if (sign_a < 0)
big_twos( dividend, length_a);
if (sign_b < 0)
big_twos( divisor, length_a);
int lg2a, lg2b, shift;
lg2a = big_log2(dividend, length_a);
lg2b = big_log2(divisor, length_a);
shift = lg2a - lg2b;
if (shift > 0)
big_shl(divisor, length_a, shift);
for (int n = 0; n <= (shift); n++)
{
big_shl(op_a, length_a, 1);
if (big_cmp( divisor, length_a, dividend, length_a ) <= 0)
{
op_a[0] |= 1;
big_sub( dividend, length_a, divisor, length_a );
}
big_shr( divisor, length_b, 1);
}
if ((sign_a < 0) != (sign_b < 0))
big_twos(op_a, length_a);
if (sign_a < 0)
big_twos(dividend, length_a);
memcpy( op_b, dividend, length_b << 2);
}

BIN
big.impl/bigint.o 100644

Binary file not shown.

Binary file not shown.

48
ln.biginteger.sln 100644
View File

@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.biginteger", "ln.biginteger\ln.biginteger.csproj", "{25072D31-5A85-4114-8C11-37299240E494}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.biginteger.test", "ln.biginteger.test\ln.biginteger.test.csproj", "{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{25072D31-5A85-4114-8C11-37299240E494}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Debug|x64.ActiveCfg = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Debug|x64.Build.0 = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Debug|x86.ActiveCfg = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Debug|x86.Build.0 = Debug|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|Any CPU.Build.0 = Release|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|x64.ActiveCfg = Release|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|x64.Build.0 = Release|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|x86.ActiveCfg = Release|Any CPU
{25072D31-5A85-4114-8C11-37299240E494}.Release|x86.Build.0 = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x64.ActiveCfg = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x64.Build.0 = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x86.ActiveCfg = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x86.Build.0 = Debug|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|Any CPU.Build.0 = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x64.ActiveCfg = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x64.Build.0 = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x86.ActiveCfg = Release|Any CPU
{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,84 @@
using NUnit.Framework;
namespace ln.biginteger.test
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test_01_BigInteger()
{
Assert.AreEqual(1, BigInteger.Zero.GetLength());
Assert.AreEqual(1, BigInteger.One.GetLength());
Assert.AreEqual(2, new BigInteger(long.MaxValue).GetLength());
Assert.AreEqual(2, new BigInteger(long.MinValue).GetLength());
Assert.AreEqual(1, new BigInteger((long)1234).GetLength());
Assert.AreEqual(BigInteger.One, BigInteger.MinusOne.Twos());
Assert.AreEqual(BigInteger.MinusOne, BigInteger.One.Twos());
Assert.AreEqual(BigInteger.Zero, BigInteger.Zero.Twos());
Assert.IsTrue(BigInteger.Zero.IsZero);
Assert.IsFalse(BigInteger.One.IsZero);
Assert.AreEqual(BigInteger.One, BigInteger.Zero.Add(BigInteger.One));
Assert.AreEqual(BigInteger.One, BigInteger.One.Add(BigInteger.Zero));
Assert.AreNotEqual(BigInteger.Zero, BigInteger.Zero.Add(BigInteger.One));
Assert.AreEqual(BigInteger.Zero, BigInteger.One.Sub(BigInteger.One));
Assert.AreEqual(BigInteger.One, BigInteger.One.Sub(BigInteger.Zero));
BigInteger bi5 = new BigInteger(5 << 24);
BigInteger bi15 = new BigInteger(15 << 24 );
BigInteger bi75 = new BigInteger(75L << 48 );
BigInteger bi75b = bi5.Mul(bi15);
Assert.AreEqual(bi75, bi75b);
Assert.AreEqual(new BigInteger(5), bi5 >> 24);
Assert.Pass();
}
[Test]
public void Test_20_Converter()
{
foreach (string hexdigits in new string[]{
"44BBCCDD",
"FFFFFFFF",
"1122334455667788",
"778899AABBCCDDEE"
})
TestImplHexConvert(hexdigits);
}
public void TestImplHexConvert(string hexdigits)
{
BigInteger bi = BigInteger.FromHexString(hexdigits);
string rehexed = bi.ToHexString();
Assert.AreEqual(hexdigits, rehexed);
}
struct TestVector
{
public uint[] a,b,c;
public TestVector(uint[] a,uint[] b, uint[] c)
{
this.a = a;
this.b = b;
this.c = c;
}
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0"/>
<ProjectReference Include="../ln.biginteger/ln.biginteger.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,899 @@
using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace ln.biginteger
{
public class BigInteger : IComparable<BigInteger>
{
public static readonly BigInteger Zero = new BigInteger();
public static readonly BigInteger One = new BigInteger(1);
public static readonly BigInteger MinusOne = new BigInteger(-1);
UInt32[] bits;
public BigInteger()
{
this.bits = new UInt32[1];
}
public BigInteger(UInt32 ui)
{
this.bits = new uint[]{ ui };
}
public BigInteger(Int32 i)
{
this.bits = new uint[]{ (uint)i };
}
public BigInteger(UInt64 i)
{
this.bits = new uint[]{
(uint)(i & 0xFFFFFFFF),
(uint)(i >> 32),
0
};
Reduce();
}
public BigInteger(Int64 i)
{
this.bits = new uint[]{
(uint)(i & 0xFFFFFFFF),
(uint)(i >> 32)
};
Reduce();
}
public BigInteger(UInt32[] rawbits)
{
bits = rawbits;
if (!Reduce())
bits = (UInt32[])bits.Clone();
}
private bool Reduce()
{
Int32 rl = GetLength();
if (bits.Length > rl)
{
UInt32[] newbits = new uint[rl];
Array.Copy(bits, newbits, rl);
bits = newbits;
return true;
}
return false;
}
public Int32 GetByteCount() => big_get_length(bits) << 2;
public Int32 GetBitLength() => big_get_length(bits) << 5;
public Int32 GetLength() => big_get_length(bits);
public int CompareTo(BigInteger other) => big_cmp(bits, bits.Length, other.bits, other.bits.Length);
public Int32 Sign {
get {
if ((bits.Length == 1) && (bits[0] == 0))
return 0;
else if ((bits[bits.Length-1] & 0x80000000) != 0)
return -1;
else
return 1;
}
}
public bool IsZero => ((bits.Length == 1) && (bits[0] == 0));
public BigInteger Add(BigInteger bi2)
{
UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1];
Array.Copy(bits,r,bits.Length);
big_add(r, r.Length, bi2.bits, bi2.bits.Length);
return new BigInteger(r);
}
public BigInteger Sub(BigInteger bi2)
{
UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1];
Array.Copy(bits,r,bits.Length);
big_sub(r, r.Length, bi2.bits, bi2.bits.Length);
return new BigInteger(r);
}
// public BigInteger Sub(BigInteger bi2)
// {
// UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1];
// Array.Copy(bits,r,bits.Length);
// UInt32[] r2 = (uint[])bi2.bits.Clone();
// big_twos(r2, r2.Length);
// big_add(r, r.Length, r2, r2.Length);
// return new BigInteger(r);
// }
public BigInteger Mul(BigInteger bi2)
{
UInt32[] r = new uint[bits.Length + bi2.bits.Length];
big_smul(bits, bits.Length, bi2.bits, bi2.bits.Length, r);
return new BigInteger(r);
}
public BigInteger DivMod(BigInteger divisor,out BigInteger remainder)
{
UInt32[] quotient = (uint[])bits.Clone();
UInt32[] d = (uint[])divisor.bits.Clone();
big_divmod( quotient, quotient.Length, d, d.Length);
remainder = new BigInteger(d);
return new BigInteger(quotient);
}
public BigInteger Div(BigInteger divisor)
{
UInt32[] quotient = (uint[])bits.Clone();
UInt32[] d = (uint[])divisor.bits.Clone();
big_divmod( quotient, quotient.Length, d, d.Length);
return new BigInteger(quotient);
}
public BigInteger Mod(BigInteger divisor)
{
UInt32[] quotient = (uint[])bits.Clone();
UInt32[] d = (uint[])divisor.bits.Clone();
big_divmod( quotient, quotient.Length, d, d.Length);
return new BigInteger(d);
}
public BigInteger Ones()
{
UInt32[] r = (UInt32[])bits.Clone();
for (int n=0;n<r.Length;n++)
r[n] = ~r[n];
return new BigInteger(r);
}
public BigInteger Twos()
{
UInt32[] r = (UInt32[])bits.Clone();
big_twos(r, r.Length);
return new BigInteger(r);
}
public BigInteger ShiftLeft(int n)
{
UInt32[] r = (UInt32[])bits.Clone();
big_shl(r, r.Length, n);
return new BigInteger(r);
}
public BigInteger ShiftRight(int n)
{
UInt32[] r = (UInt32[])bits.Clone();
big_shr(r, r.Length, n);
return new BigInteger(r);
}
public override bool Equals(object obj)
{
if (obj is BigInteger bi2)
{
if (bits.Length == bi2.bits.Length)
{
for (int n=0;n<bits.Length;n++)
{
if (bits[n] != bi2.bits[n])
return false;
}
return true;
}
}
return false;
}
public byte[] ToByteArray()
{
bool nonzero = false;
MemoryStream ms = new MemoryStream();
// if (Sign < 0)
// ms.WriteByte(0);
for (int n=bits.Length-1; n >= 0; n--)
{
for (int m=3; m>=0; m--)
{
byte tb = (byte)((bits[n] >> (m*8)) & 0xff);
if (nonzero || (tb!=0))
{
nonzero = true;
ms.WriteByte(tb);
}
}
}
return ms.ToArray();
}
public static BigInteger operator+(BigInteger bi1,BigInteger bi2) => bi1.Add(bi2);
public static BigInteger operator-(BigInteger bi1,BigInteger bi2) => bi1.Sub(bi2);
public static BigInteger operator<<(BigInteger bi, int n) => bi.ShiftLeft(n);
public static BigInteger operator>>(BigInteger bi, int n) => bi.ShiftRight(n);
public static BigInteger FromHexString(string hex)
{
hex = hex.ToUpper();
int length = (hex.Length+7) >> 3;
UInt32[] bits = new uint[length];
int n;
for (n=hex.Length-8; n>=0; n -= 8)
bits[length - 1 - (n >> 3)] = uint.Parse(hex.Substring(n,8), NumberStyles.HexNumber);
if (n > -8)
bits[length - 1] = uint.Parse(hex.Substring(0, 8 + n), NumberStyles.HexNumber);
return new BigInteger(bits);
}
public string ToHexString()
{
byte[] bytes = ToByteArray();
StringBuilder sb = new StringBuilder();
foreach (byte by in bytes)
sb.AppendFormat("{0:X2}", by);
return sb.ToString();
}
// public BigInteger(UInt32[] value)
// {
// this.bits = value;
// }
// public BigInteger(byte[] ivalue)
// {
// UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2];
// ivalue = ivalue.Segment(0, v.Length << 2);
// for (int n = 0; n < v.Length; n++)
// {
// v[n] = BitConverter.ToUInt32(ivalue, n << 2);
// }
// this.bits = BigIntMath.reduceSigned(v);
// }
// public BigInteger(BigInteger src)
// {
// this.bits = src.bits;
// }
// public bool IsZero => BigIntMath.isZero(bits);
// public int Sign => BigIntMath.isZero(bits) ? 0 : BigIntMath.sign(bits) ? -1 : 1;
// public int GetByteCount() => bits.Length * 4;
// public int GetBitLength() => BigIntMath.log2(bits);
// public byte[] ToByteArray() => bits.GetBytes();
// public void TryWriteBytes(Span<byte> s,out int bytesWritten)
// {
// byte[] sb = ToByteArray();
// for (bytesWritten = 0; bytesWritten < sb.Length; bytesWritten++)
// s[bytesWritten] = sb[bytesWritten];
// }
// public int Log2(){
// return BigIntMath.log2(bits);
// }
// public static BigInteger ModPow(BigInteger i,int n,BigInteger modulus)
// {
// BigInteger r = BigInteger.One;
// while (n-- > 0)
// {
// r *= i;
// r %= modulus;
// }
// return r;
// }
// public BigInteger Pow(int n)
// {
// if (n == 0)
// {
// return One;
// }
// else if (n == 1)
// {
// return this;
// }
// else if (n > 1)
// {
// BigInteger result = this;
// n--;
// while ((n--) > 0)
// {
// result = (result * this);
// }
// return result;
// }
// throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
// }
// public BigInteger Ones()
// {
// UInt32[] result = BigIntMath.ones(bits);
// return new BigInteger(result);
// }
// public BigInteger Twos()
// {
// UInt32[] result = BigIntMath.twos(bits);
// return new BigInteger(result);
// }
// public static BigInteger fromHexString(string hex) => Parse(hex, 16);
// public override string ToString()
// {
// return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, ToString(16), Sign );
// }
// public string ToString(string format)
// {
// if (format.Equals("X"))
// return ToString(16);
// return ToString(10);
// }
// public string ToString(int radix) => ToString(radix, -1);
// public string ToString(int radix, int length)
// {
// if ((radix < 2) || (radix > 36))
// throw new ArgumentOutOfRangeException(nameof(radix));
// uint[] v = bits.Segment(0);
// uint[] r = new uint[]{ (uint)radix };
// StringBuilder sb = new StringBuilder();
// while ((!BigIntMath.isZero(v)) && ((length-- )!=0))
// {
// uint[] x = BigIntMath.sdivmod(ref v, r);
// if (v[0] < 10)
// sb.Append((char)('0' + v[0]));
// else
// sb.Append((char)(55 + v[0]));
// v = x;
// }
// char[] result = new char[sb.Length];
// sb.CopyTo(0, result, 0, sb.Length);
// Array.Reverse(result);
// return new string(result);
// }
// public static BigInteger Parse(string input) => Parse(input, 10);
// public static BigInteger Parse(string input, NumberStyles numberStyles)
// {
// if ((numberStyles & (NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier)) != 0)
// return Parse(input, 16);
// return Parse(input, 10);
// }
// public static BigInteger Parse(string input, int radix)
// {
// BigInteger v = 0;
// bool sign = false;
// if (input[0] == '-')
// {
// sign = true;
// input = input.Substring(1);
// }
// foreach (char d in input)
// {
// int n = d - '0';
// if (n > 9)
// n = d - 55;
// v *= radix;
// v += n;
// }
// if (sign)
// v = v.Twos();
// return v;
// }
// private BigInteger __op_add(BigInteger b)
// {
// int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1;
// UInt32[] v = BigIntMath.extendSigned(bits, width);
// UInt32[] vb = BigIntMath.extendSigned(b.bits, width);
// return new BigInteger(BigIntMath.reduceSigned(BigIntMath.add(v,vb)));
// }
// private BigInteger __op_sub(BigInteger b)
// {
// int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1;
// UInt32[] v = BigIntMath.extendSigned(bits, width);
// UInt32[] vb = BigIntMath.extendSigned(b.bits, width);
// return new BigInteger(BigIntMath.reduceSigned(BigIntMath.sub(v,vb)));
// }
// private int __op_cmp(BigInteger b)
// {
// return BigIntMath.cmp(bits, b.bits);
// }
// private BigInteger __op_div(BigInteger b)
// {
// UInt32[] result = BigIntMath.sdiv(bits, b.bits);
// return new BigInteger(result);
// }
// private BigInteger __op_mod(BigInteger b)
// {
// UInt32[] result = BigIntMath.smod(bits, b.bits);
// return new BigInteger(result);
// }
// private BigInteger __op_mul(BigInteger b)
// {
// UInt32[] value = BigIntMath.smul(bits, b.bits);
// return new BigInteger(value);
// }
// private BigInteger __op_new(uint[] value)
// {
// return new BigInteger(value);
// }
// private BigInteger __op_shl(int b)
// {
// UInt32[] value = BigIntMath.extendSigned(bits, bits.Length + ((b + 31) >> 5));
// BigIntMath.shl(value,b);
// return new BigInteger(value);
// }
// private BigInteger __op_shr(int b)
// {
// UInt32[] value = bits.Segment(0);
// BigIntMath.shr(value, b);
// return new BigInteger(value);
// }
// public static implicit operator BigInteger(int i)
// {
// return new BigInteger(new UInt32[]{(UInt32)i});
// }
// public static BigInteger operator +(BigInteger a, BigInteger b)
// {
// return a.__op_add(b);
// }
// public static BigInteger operator -(BigInteger a, BigInteger b)
// {
// return a.__op_sub(b);
// }
// public static BigInteger operator *(BigInteger a, BigInteger b)
// {
// return a.__op_mul(b);
// }
// public static BigInteger operator /(BigInteger a, BigInteger b)
// {
// return a.__op_div(b);
// }
// public static BigInteger operator %(BigInteger a, BigInteger b)
// {
// return a.__op_mod(b);
// }
// public static bool operator <(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) < 0;
// }
// public static bool operator >(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) > 0;
// }
// public static bool operator ==(BigInteger a, BigInteger b)
// {
// if ((object)a == (object)b)
// {
// return true;
// }
// if (((object)a == null) || ((object)b == null))
// {
// return false;
// }
// return a.__op_cmp(b) == 0;
// }
// public static bool operator !=(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) != 0;
// }
// public static BigInteger operator <<(BigInteger a, int b)
// {
// return a.__op_shl(b);
// }
// public static BigInteger operator >>(BigInteger a, int b)
// {
// return a.__op_shr(b);
// }
// public override bool Equals(object obj) => (obj is BigInteger other) && (this == other);
// public override int GetHashCode() => ToByteArray().CreateHashCode();
/*** Native Implementations ***/
// public BigInteger(UInt32[] value)
// {
// this.bits = value;
// }
// public BigInteger(byte[] ivalue)
// {
// UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2];
// ivalue = ivalue.Segment(0, v.Length << 2);
// for (int n = 0; n < v.Length; n++)
// {
// v[n] = BitConverter.ToUInt32(ivalue, n << 2);
// }
// this.bits = BigIntMath.reduceSigned(v);
// }
// public BigInteger(BigInteger src)
// {
// this.bits = src.bits;
// }
// public bool IsZero => BigIntMath.isZero(bits);
// public int Sign => BigIntMath.isZero(bits) ? 0 : BigIntMath.sign(bits) ? -1 : 1;
// public int GetByteCount() => bits.Length * 4;
// public int GetBitLength() => BigIntMath.log2(bits);
// public byte[] ToByteArray() => bits.GetBytes();
// public void TryWriteBytes(Span<byte> s,out int bytesWritten)
// {
// byte[] sb = ToByteArray();
// for (bytesWritten = 0; bytesWritten < sb.Length; bytesWritten++)
// s[bytesWritten] = sb[bytesWritten];
// }
// public int Log2(){
// return BigIntMath.log2(bits);
// }
// public static BigInteger ModPow(BigInteger i,int n,BigInteger modulus)
// {
// BigInteger r = BigInteger.One;
// while (n-- > 0)
// {
// r *= i;
// r %= modulus;
// }
// return r;
// }
// public BigInteger Pow(int n)
// {
// if (n == 0)
// {
// return One;
// }
// else if (n == 1)
// {
// return this;
// }
// else if (n > 1)
// {
// BigInteger result = this;
// n--;
// while ((n--) > 0)
// {
// result = (result * this);
// }
// return result;
// }
// throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
// }
// public BigInteger Ones()
// {
// UInt32[] result = BigIntMath.ones(bits);
// return new BigInteger(result);
// }
// public BigInteger Twos()
// {
// UInt32[] result = BigIntMath.twos(bits);
// return new BigInteger(result);
// }
// public static BigInteger fromHexString(string hex) => Parse(hex, 16);
// public override string ToString()
// {
// return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, ToString(16), Sign );
// }
// public string ToString(string format)
// {
// if (format.Equals("X"))
// return ToString(16);
// return ToString(10);
// }
// public string ToString(int radix) => ToString(radix, -1);
// public string ToString(int radix, int length)
// {
// if ((radix < 2) || (radix > 36))
// throw new ArgumentOutOfRangeException(nameof(radix));
// uint[] v = bits.Segment(0);
// uint[] r = new uint[]{ (uint)radix };
// StringBuilder sb = new StringBuilder();
// while ((!BigIntMath.isZero(v)) && ((length-- )!=0))
// {
// uint[] x = BigIntMath.sdivmod(ref v, r);
// if (v[0] < 10)
// sb.Append((char)('0' + v[0]));
// else
// sb.Append((char)(55 + v[0]));
// v = x;
// }
// char[] result = new char[sb.Length];
// sb.CopyTo(0, result, 0, sb.Length);
// Array.Reverse(result);
// return new string(result);
// }
// public static BigInteger Parse(string input) => Parse(input, 10);
// public static BigInteger Parse(string input, NumberStyles numberStyles)
// {
// if ((numberStyles & (NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier)) != 0)
// return Parse(input, 16);
// return Parse(input, 10);
// }
// public static BigInteger Parse(string input, int radix)
// {
// BigInteger v = 0;
// bool sign = false;
// if (input[0] == '-')
// {
// sign = true;
// input = input.Substring(1);
// }
// foreach (char d in input)
// {
// int n = d - '0';
// if (n > 9)
// n = d - 55;
// v *= radix;
// v += n;
// }
// if (sign)
// v = v.Twos();
// return v;
// }
// private BigInteger __op_add(BigInteger b)
// {
// int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1;
// UInt32[] v = BigIntMath.extendSigned(bits, width);
// UInt32[] vb = BigIntMath.extendSigned(b.bits, width);
// return new BigInteger(BigIntMath.reduceSigned(BigIntMath.add(v,vb)));
// }
// private BigInteger __op_sub(BigInteger b)
// {
// int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1;
// UInt32[] v = BigIntMath.extendSigned(bits, width);
// UInt32[] vb = BigIntMath.extendSigned(b.bits, width);
// return new BigInteger(BigIntMath.reduceSigned(BigIntMath.sub(v,vb)));
// }
// private int __op_cmp(BigInteger b)
// {
// return BigIntMath.cmp(bits, b.bits);
// }
// private BigInteger __op_div(BigInteger b)
// {
// UInt32[] result = BigIntMath.sdiv(bits, b.bits);
// return new BigInteger(result);
// }
// private BigInteger __op_mod(BigInteger b)
// {
// UInt32[] result = BigIntMath.smod(bits, b.bits);
// return new BigInteger(result);
// }
// private BigInteger __op_mul(BigInteger b)
// {
// UInt32[] value = BigIntMath.smul(bits, b.bits);
// return new BigInteger(value);
// }
// private BigInteger __op_new(uint[] value)
// {
// return new BigInteger(value);
// }
// private BigInteger __op_shl(int b)
// {
// UInt32[] value = BigIntMath.extendSigned(bits, bits.Length + ((b + 31) >> 5));
// BigIntMath.shl(value,b);
// return new BigInteger(value);
// }
// private BigInteger __op_shr(int b)
// {
// UInt32[] value = bits.Segment(0);
// BigIntMath.shr(value, b);
// return new BigInteger(value);
// }
// public static implicit operator BigInteger(int i)
// {
// return new BigInteger(new UInt32[]{(UInt32)i});
// }
// public static BigInteger operator +(BigInteger a, BigInteger b)
// {
// return a.__op_add(b);
// }
// public static BigInteger operator -(BigInteger a, BigInteger b)
// {
// return a.__op_sub(b);
// }
// public static BigInteger operator *(BigInteger a, BigInteger b)
// {
// return a.__op_mul(b);
// }
// public static BigInteger operator /(BigInteger a, BigInteger b)
// {
// return a.__op_div(b);
// }
// public static BigInteger operator %(BigInteger a, BigInteger b)
// {
// return a.__op_mod(b);
// }
// public static bool operator <(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) < 0;
// }
// public static bool operator >(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) > 0;
// }
// public static bool operator ==(BigInteger a, BigInteger b)
// {
// if ((object)a == (object)b)
// {
// return true;
// }
// if (((object)a == null) || ((object)b == null))
// {
// return false;
// }
// return a.__op_cmp(b) == 0;
// }
// public static bool operator !=(BigInteger a, BigInteger b)
// {
// return a.__op_cmp(b) != 0;
// }
// public static BigInteger operator <<(BigInteger a, int b)
// {
// return a.__op_shl(b);
// }
// public static BigInteger operator >>(BigInteger a, int b)
// {
// return a.__op_shr(b);
// }
// public override bool Equals(object obj) => (obj is BigInteger other) && (this == other);
// public override int GetHashCode() => ToByteArray().CreateHashCode();
/*** Native Implementations ***/
[DllImport("libbigint")]
public static extern Int32 big_get_length(UInt32[] bits, Int32 length);
public static Int32 big_get_length(UInt32[] bits) => big_get_length(bits, bits.Length);
[DllImport("libbigint")]
public static extern void big_add(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
[DllImport("libbigint")]
public static extern void big_sub(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
[DllImport("libbigint")]
public static extern void big_twos(UInt32[] bits, Int32 length);
[DllImport("libbigint")]
public static extern void big_shl(UInt32[] bits, Int32 length, Int32 n);
[DllImport("libbigint")]
public static extern void big_shr(UInt32[] bits, Int32 length, Int32 n);
[DllImport("libbigint")]
public static extern Int32 big_cmp(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
[DllImport("libbigint")]
public static extern void big_smul(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b, UInt32[] result);
[DllImport("libbigint")]
public static extern void big_divmod(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
private int max(int a,int b) => a > b ? a : b;
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Numerics;
namespace BigInt
{
public static class NumericsExtensions
{
public static System.Numerics.BigInteger Sqrt(this System.Numerics.BigInteger n)
{
if (n == 0) return 0;
if (n > 0)
{
int bitLength = Convert.ToInt32(Math.Ceiling(System.Numerics.BigInteger.Log(n, 2)));
System.Numerics.BigInteger root = System.Numerics.BigInteger.One << (bitLength / 2);
while (!isSqrt(n, root))
{
root += n / root;
root /= 2;
}
return root;
}
throw new ArithmeticException("NaN");
}
private static Boolean isSqrt(System.Numerics.BigInteger n, System.Numerics.BigInteger root)
{
System.Numerics.BigInteger lowerBound = root * root;
System.Numerics.BigInteger upperBound = (root + 1) * (root + 1);
return (n >= lowerBound && n < upperBound);
}
}
}

Binary file not shown.

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="libbigint.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>