Alpha
parent
cdc8e0cc8d
commit
b977fb217c
|
@ -1,12 +1,21 @@
|
|||
|
||||
SRC=bigint.c
|
||||
OBJECTS=bigint.o
|
||||
CFLAGS=-fPIC
|
||||
|
||||
all: distribute
|
||||
DEFTARGET:=$(shell uname)
|
||||
|
||||
all: linux Darwin
|
||||
|
||||
clean:
|
||||
rm -f ../ln.biginteger/libbigint.so ../ln.biginteger/libbigint.dylib ../ln.biginteger/libbigint.dll
|
||||
|
||||
distribute: ../ln.biginteger/libbigint.so
|
||||
|
||||
../ln.biginteger/libbigint.so: $(OBJECTS)
|
||||
gcc -shared -o ../ln.biginteger/libbigint.so $(OBJECTS)
|
||||
linux: ../ln.biginteger/libbigint.so
|
||||
../ln.biginteger/libbigint.so: $(SRC)
|
||||
gcc -shared -o ../ln.biginteger/libbigint.so $(SRC)
|
||||
|
||||
|
||||
Darwin: ../ln.biginteger/libbigint.dylib
|
||||
../ln.biginteger/libbigint.dylib: $(SRC)
|
||||
gcc -shared -o ../ln.biginteger/libbigint.dylib $(SRC)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint32_t one[] = { 1 };
|
||||
|
||||
|
@ -8,16 +9,23 @@ int32_t max(int32_t a,int32_t b)
|
|||
return a>b ? a : b;
|
||||
}
|
||||
|
||||
#define DUMP(op,l) for (int ___p = 0; ___p < l; ___p++) printf("0x%08x", op[___p]); printf("\n");
|
||||
|
||||
int32_t big_get_bitlength(uint32_t *op, int32_t length)
|
||||
{
|
||||
int32_t sign = (op[ length - 1 ] >> 31) & 0x00000001;
|
||||
for (int ni = length - 1; ni >= 0; ni--)
|
||||
for (int nb = 31; nb >= 0; nb--)
|
||||
{
|
||||
if (((op[ni] >> nb) & 0x00000001) != sign)
|
||||
return (ni << 5) + nb + 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
return (big_get_bitlength(op, length) + 31) >> 5;
|
||||
}
|
||||
|
||||
int32_t big_sign(uint32_t *op, int32_t length)
|
||||
|
@ -30,29 +38,29 @@ int32_t big_sign(uint32_t *op, int32_t length)
|
|||
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_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) & 0x1FFFFFFF))) == 0)
|
||||
// {
|
||||
// return 1 - n;
|
||||
// }
|
||||
// }
|
||||
// return 0;
|
||||
// } else {
|
||||
// for (int n = length << 5; n > 0; n--)
|
||||
// {
|
||||
// if ((op[(n - 1) >> 5] & (1 << ((n - 1) & 0x1FFFFFFF))) != 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)
|
||||
{
|
||||
|
@ -62,10 +70,12 @@ int32_t big_cmp(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length
|
|||
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)
|
||||
int d = a - b;
|
||||
|
||||
if (d > 0)
|
||||
return 1;
|
||||
else if (d < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -111,7 +121,7 @@ void big_shr(uint32_t *op, int32_t length, int32_t n)
|
|||
if (b1 < length)
|
||||
{
|
||||
op[i] = (op[b1] >> n);
|
||||
if ((b2 == length) && (s)){
|
||||
if ((b2 == length) && (s < 0)){
|
||||
op[i] |= ((0xffffffff << (32 - n)));
|
||||
} else if ((n != 0) && (b2 < length))
|
||||
{
|
||||
|
@ -127,11 +137,11 @@ void big_shr(uint32_t *op, int32_t length, int32_t n)
|
|||
|
||||
void big_add(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
|
||||
{
|
||||
uint64_t c = 0;
|
||||
int64_t c = 0;
|
||||
|
||||
for (int n=0;n<length_a;n++)
|
||||
{
|
||||
c += op_a[n] + ((n < length_b) ? op_b[n] : 0);
|
||||
c += (int64_t)op_a[n] + ((n < length_b) ? op_b[n] : 0);
|
||||
op_a[n] = (c & 0xffffffff);
|
||||
c >>= 32;
|
||||
|
||||
|
@ -142,10 +152,9 @@ void big_add(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
|
|||
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);
|
||||
c += (int64_t)op_a[n] - ((n < length_b) ? op_b[n] : 0);
|
||||
op_a[n] = (c & 0xffffffff);
|
||||
c >>= 32;
|
||||
|
||||
|
@ -161,20 +170,22 @@ void big_twos(uint32_t *op, int32_t length)
|
|||
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)
|
||||
void big_smul(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b)
|
||||
{
|
||||
int32_t l = length_a + length_b;
|
||||
uint32_t op_a_bak[length_a];
|
||||
memcpy( op_a_bak, op_a, length_a << 2);
|
||||
memset( op_a, 0x00, length_a << 2);
|
||||
|
||||
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++)
|
||||
uint64_t ui64 = ((uint64_t)op_a_bak[l1] * op_b[l2]);
|
||||
for (int ct = target; (ct < length_a) && (ui64 != 0); ct++)
|
||||
{
|
||||
ui64 += result[ct];
|
||||
result[ct] = (uint32_t)ui64;
|
||||
ui64 += op_a[ct];
|
||||
op_a[ct] = (uint32_t)ui64;
|
||||
ui64 >>= 32;
|
||||
}
|
||||
}
|
||||
|
@ -186,10 +197,13 @@ void big_divmod(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length
|
|||
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];
|
||||
int l = max(length_a, length_b);
|
||||
|
||||
memset( divisor, 0x00, sizeof(divisor) );
|
||||
uint32_t dividend[l];
|
||||
uint32_t divisor[l];
|
||||
|
||||
memset( dividend, 0x00, l<<2 );
|
||||
memset( divisor, 0x00, l<<2 );
|
||||
|
||||
memcpy( dividend, op_a, length_a << 2);
|
||||
memcpy( divisor, op_b, length_b << 2);
|
||||
|
@ -197,36 +211,54 @@ void big_divmod(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length
|
|||
memset( op_a, 0x00, length_a << 2);
|
||||
|
||||
if (sign_a < 0)
|
||||
big_twos( dividend, length_a);
|
||||
big_twos( dividend, l);
|
||||
if (sign_b < 0)
|
||||
big_twos( divisor, length_a);
|
||||
big_twos( divisor, l);
|
||||
|
||||
int lg2a, lg2b, shift;
|
||||
|
||||
lg2a = big_log2(dividend, length_a);
|
||||
lg2b = big_log2(divisor, length_a);
|
||||
lg2a = big_get_bitlength(dividend, l);
|
||||
lg2b = big_get_bitlength(divisor, l);
|
||||
shift = lg2a - lg2b;
|
||||
|
||||
if (shift > 0)
|
||||
big_shl(divisor, length_a, shift);
|
||||
big_shl(divisor, l, 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)
|
||||
if (big_cmp( divisor, l, dividend, l ) <= 0)
|
||||
{
|
||||
op_a[0] |= 1;
|
||||
big_sub( dividend, length_a, divisor, length_a );
|
||||
big_sub( dividend, l, divisor, l );
|
||||
}
|
||||
|
||||
big_shr( divisor, length_b, 1);
|
||||
big_shr( divisor, l, 1);
|
||||
}
|
||||
|
||||
if ((sign_a < 0) != (sign_b < 0))
|
||||
big_twos(op_a, length_a);
|
||||
if (sign_a < 0)
|
||||
big_twos(dividend, length_a);
|
||||
big_twos(dividend, l);
|
||||
|
||||
memcpy( op_b, dividend, length_b << 2);
|
||||
}
|
||||
|
||||
int32_t big_parse(uint32_t* op, int32_t length, char *source, int32_t radix)
|
||||
{
|
||||
int sl = strlen(source);
|
||||
memset( op, 0x00, length << 2);
|
||||
for (int n=0;n<sl;n++)
|
||||
{
|
||||
uint32_t v = source[n] - '0';
|
||||
if (v > 9)
|
||||
v = source[n] - 55;
|
||||
if (v > 36)
|
||||
v = source[n] - 87;
|
||||
|
||||
big_smul(op, length, (uint32_t*)&radix, 1);
|
||||
big_add(op, length, (uint32_t*)&v, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace ln.biginteger.test
|
||||
{
|
||||
|
@ -10,43 +11,264 @@ namespace ln.biginteger.test
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void Test_01_BigInteger()
|
||||
public void Test_00_LowLevel()
|
||||
{
|
||||
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());
|
||||
UInt32[] a,b,c;
|
||||
Int32 d;
|
||||
|
||||
Assert.AreEqual(BigInteger.One, BigInteger.MinusOne.Twos());
|
||||
Assert.AreEqual(BigInteger.MinusOne, BigInteger.One.Twos());
|
||||
Assert.AreEqual(BigInteger.Zero, BigInteger.Zero.Twos());
|
||||
a = new UInt32[]{ 0x00000000, 0x00000000 };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 1 , d );
|
||||
|
||||
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));
|
||||
a = new UInt32[]{ 0x00000001, 0x00000000 };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 2 , d );
|
||||
|
||||
Assert.AreEqual(BigInteger.Zero, BigInteger.One.Sub(BigInteger.One));
|
||||
Assert.AreEqual(BigInteger.One, BigInteger.One.Sub(BigInteger.Zero));
|
||||
a = new UInt32[]{ 0x00001000, 0x00000000 };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 14 , d );
|
||||
|
||||
BigInteger bi5 = new BigInteger(5 << 24);
|
||||
BigInteger bi15 = new BigInteger(15 << 24 );
|
||||
BigInteger bi75 = new BigInteger(75L << 48 );
|
||||
BigInteger bi75b = bi5.Mul(bi15);
|
||||
a = new UInt32[]{ 0xFFFF8000, 0x00000000 };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 33 , d );
|
||||
|
||||
Assert.AreEqual(bi75, bi75b);
|
||||
Assert.AreEqual(new BigInteger(5), bi5 >> 24);
|
||||
a = new UInt32[]{ 0xFFFF8000, 0xFFFFFFFF };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 16 , d );
|
||||
|
||||
a = new UInt32[]{ 0xFC000000 };
|
||||
d = BigInteger.big_get_bitlength( a, a.Length );
|
||||
Assert.AreEqual( 27 , d );
|
||||
|
||||
a = new uint[]{0};
|
||||
b = new uint[]{0, 0};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{0};
|
||||
b = new uint[]{0, 0, 0, 0};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{1};
|
||||
b = new uint[]{1, 0, 0, 0};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{5463782};
|
||||
b = new uint[]{5463782, 0, 0, 0};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{ 0xFFFFEDCB };
|
||||
b = new uint[]{ 0xFFFFEDCB, 0xFFFFFFFF};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{ 0xFFFFEDCB };
|
||||
b = new uint[]{ 0xFFFFEDCB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{ 0xFFFFEDCB, 0xFFFFFFFF };
|
||||
b = new uint[]{ 0xFFFFEDCB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||
c = BigInteger.Extend(a, b.Length);
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a = new uint[]{ 0xFFFFFFFF };
|
||||
b = new uint[]{ 0x00000001 };
|
||||
BigInteger.big_twos( a, a.Length );
|
||||
Assert.AreEqual(b, a);
|
||||
|
||||
a = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
b = new uint[]{ 0x00000001, 0x00000000 };
|
||||
BigInteger.big_twos( a, a.Length );
|
||||
Assert.AreEqual(b, a);
|
||||
|
||||
a = new uint[]{ 0x01000020 };
|
||||
b = new uint[]{ 0x00100002 };
|
||||
BigInteger.big_shr( a, a.Length, 4);
|
||||
Assert.AreEqual(b, a);
|
||||
|
||||
a = new uint[]{ 0x10000000 };
|
||||
b = new uint[]{ 0x08000000 };
|
||||
BigInteger.big_shr( a, a.Length, 1);
|
||||
Assert.AreEqual(b, a);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Test_01_LL_AddSub()
|
||||
{
|
||||
UInt32[] a,b,c;
|
||||
|
||||
a = new UInt32[]{ 0x00000000 };
|
||||
b = new UInt32[]{ 0x00000000 };
|
||||
c = new UInt32[]{ 0x00000000 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00000123 };
|
||||
b = new UInt32[]{ 0x00123000 };
|
||||
c = new UInt32[]{ 0x00123123 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00000123 };
|
||||
b = new UInt32[]{ 0x00000123 };
|
||||
c = new UInt32[]{ 0x00000246 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00123456 };
|
||||
b = new UInt32[]{ 0x00345678 };
|
||||
c = new UInt32[]{ 0x00468ACE };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x70004567, 0x00000000 };
|
||||
b = new UInt32[]{ 0x10000000 };
|
||||
c = new UInt32[]{ 0x80004567, 0x00000000 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x70004567, 0x00000000 };
|
||||
b = new UInt32[]{ 0x20000000 };
|
||||
c = new UInt32[]{ 0x90004567, 0x00000000 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x70004567, 0x00000000 };
|
||||
b = new UInt32[]{ 0xA0000000 };
|
||||
c = new UInt32[]{ 0x10004567, 0x00000001 };
|
||||
BigInteger.big_add( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00000000 };
|
||||
b = new UInt32[]{ 0x00000001 };
|
||||
c = new UInt32[]{ 0xFFFFFFFF };
|
||||
BigInteger.big_sub( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00000000, 0x00000000 };
|
||||
b = new UInt32[]{ 0x00000001 };
|
||||
c = new UInt32[]{ 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
BigInteger.big_sub( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x00000000, 0xF0000000 };
|
||||
b = new UInt32[]{ 0x00000001 };
|
||||
c = new UInt32[]{ 0xFFFFFFFF, 0xEFFFFFFF };
|
||||
BigInteger.big_sub( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x54A5D32F, 0xD25AC351 };
|
||||
b = new UInt32[]{ 0xC351425A, 0x432F54A5 };
|
||||
c = new UInt32[]{ 0x915490D5, 0x8F2B6EAB };
|
||||
BigInteger.big_sub( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_02_LL_Mul()
|
||||
{
|
||||
UInt32[] a,b,c;
|
||||
|
||||
a = new UInt32[]{ 0x00000200 };
|
||||
b = new UInt32[]{ 0x00000300 };
|
||||
c = new UInt32[]{ 0x00060000 };
|
||||
BigInteger.big_smul( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0xD25AC351, 0x00000000 };
|
||||
b = new UInt32[]{ 0x432F54A5 };
|
||||
c = new UInt32[]{ 0x6B757735, 0x3734A555 };
|
||||
BigInteger.big_smul( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0xFFFFFFFF };
|
||||
b = new UInt32[]{ 0x00000001 };
|
||||
c = new UInt32[]{ 0xFFFFFFFF };
|
||||
BigInteger.big_smul( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0xFFFFFFFF };
|
||||
b = new UInt32[]{ 0xFFFFFFFF };
|
||||
c = new UInt32[]{ 0x00000001 };
|
||||
BigInteger.big_smul( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_LL_Div()
|
||||
{
|
||||
UInt32[] a,b,c;
|
||||
Int32 d;
|
||||
|
||||
a = new UInt32[]{ 0x12345678 };
|
||||
b = new UInt32[]{ 0x00000001 };
|
||||
c = new UInt32[]{ 0x12345678 };
|
||||
BigInteger.big_divmod( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
|
||||
a = new UInt32[]{ 0x12345678 };
|
||||
b = new UInt32[]{ 0x00000032 };
|
||||
c = new UInt32[]{ 0x005D34ED };
|
||||
d = 0x2E;
|
||||
BigInteger.big_divmod( a, b );
|
||||
Assert.AreEqual( c, a );
|
||||
Assert.AreEqual( d, b[0] );
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_14_HL_Pow()
|
||||
{
|
||||
BigInteger a,b,c;
|
||||
|
||||
a = BigInteger.FromHexString("34");
|
||||
b = a.Pow(7);
|
||||
c = BigInteger.FromHexString("0EF5DD94000");
|
||||
Assert.AreEqual(c, b);
|
||||
|
||||
a = BigInteger.FromHexString("34");
|
||||
b = a.Pow(5);
|
||||
c = BigInteger.FromHexString("16A97400");
|
||||
Assert.AreEqual(c, b);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
[Test]
|
||||
public void Test_20_Converter()
|
||||
{
|
||||
|
@ -61,8 +283,8 @@ namespace ln.biginteger.test
|
|||
|
||||
public void TestImplHexConvert(string hexdigits)
|
||||
{
|
||||
BigInteger bi = BigInteger.FromHexString(hexdigits);
|
||||
string rehexed = bi.ToHexString();
|
||||
BigInteger bi = BigInteger.Parse(hexdigits, 16);
|
||||
string rehexed = bi.ToString(16);
|
||||
Assert.AreEqual(hexdigits, rehexed);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,26 +47,36 @@ namespace ln.biginteger
|
|||
|
||||
public BigInteger(UInt32[] rawbits)
|
||||
{
|
||||
bits = rawbits;
|
||||
if (!Reduce())
|
||||
bits = (UInt32[])bits.Clone();
|
||||
bits = Reduce(rawbits);
|
||||
}
|
||||
|
||||
private bool Reduce()
|
||||
private void Reduce() => bits = Reduce(bits);
|
||||
public static UInt32[] Reduce(UInt32[] bits)
|
||||
{
|
||||
Int32 rl = GetLength();
|
||||
Int32 rl = big_get_length(bits);
|
||||
if (bits.Length > rl)
|
||||
{
|
||||
UInt32[] newbits = new uint[rl];
|
||||
Array.Copy(bits, newbits, rl);
|
||||
bits = newbits;
|
||||
return true;
|
||||
} else {
|
||||
bits = (UInt32[])bits.Clone();
|
||||
}
|
||||
return false;
|
||||
return bits;
|
||||
}
|
||||
|
||||
public static UInt32[] Extend(UInt32[] bits, int length)
|
||||
{
|
||||
UInt32[] extendedbits = new UInt32[length];
|
||||
Array.Copy(bits, extendedbits, bits.Length);
|
||||
if ((bits[bits.Length-1] & 0x80000000)==0x80000000)
|
||||
for (int n=bits.Length; n<extendedbits.Length; n++)
|
||||
extendedbits[n] = 0xFFFFFFFF;
|
||||
return extendedbits;
|
||||
}
|
||||
|
||||
public Int32 GetByteCount() => big_get_length(bits) << 2;
|
||||
public Int32 GetBitLength() => big_get_length(bits) << 5;
|
||||
public Int32 GetBitLength() => big_get_bitlength(bits) << 5;
|
||||
public Int32 GetLength() => big_get_length(bits);
|
||||
|
||||
public int CompareTo(BigInteger other) => big_cmp(bits, bits.Length, other.bits, other.bits.Length);
|
||||
|
@ -88,18 +98,21 @@ namespace ln.biginteger
|
|||
|
||||
public BigInteger Add(BigInteger bi2)
|
||||
{
|
||||
UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1];
|
||||
int tlength = max(big_get_bitlength(bits), big_get_bitlength(bi2.bits))+1;
|
||||
UInt32[] r = new uint[(tlength + 31)>>5];
|
||||
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];
|
||||
int tlength = max(big_get_bitlength(bits), big_get_bitlength(bi2.bits))+1;
|
||||
UInt32[] r = new uint[(tlength + 31)>>5];
|
||||
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];
|
||||
|
@ -114,8 +127,10 @@ namespace ln.biginteger
|
|||
|
||||
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);
|
||||
int l = (big_get_bitlength(bits) + big_get_bitlength(bi2.bits) + 31) >> 5;
|
||||
UInt32[] r = new UInt32[l];
|
||||
Array.Copy(bits, r, bits.Length);
|
||||
big_smul(r, bi2.bits);
|
||||
return new BigInteger(r);
|
||||
}
|
||||
|
||||
|
@ -177,7 +192,27 @@ namespace ln.biginteger
|
|||
big_shr(r, r.Length, n);
|
||||
return new BigInteger(r);
|
||||
}
|
||||
|
||||
public BigInteger Pow(int n)
|
||||
{
|
||||
if (n == 0)
|
||||
return One;
|
||||
else if (n == 1)
|
||||
return this;
|
||||
else if (n == 2)
|
||||
return this * this;
|
||||
else if (n > 2)
|
||||
{
|
||||
BigInteger result = One;
|
||||
for (int i=31; i>=0; i--)
|
||||
{
|
||||
result *= result;
|
||||
if ((n & (1<<i))!=0)
|
||||
result *= this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -230,24 +265,35 @@ namespace ln.biginteger
|
|||
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 operator*(BigInteger bi1,BigInteger bi2) => bi1.Mul(bi2);
|
||||
public static BigInteger operator/(BigInteger bi1,BigInteger bi2) => bi1.Div(bi2);
|
||||
public static BigInteger operator%(BigInteger bi1,BigInteger bi2) => bi1.Mod(bi2);
|
||||
//public static BigInteger operator^(BigInteger bi1,int exp) => bi1.Pow(exp);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static BigInteger Parse(string source) => Parse( source, 10 );
|
||||
public static BigInteger Parse(string source,int radix)
|
||||
{
|
||||
UInt32[] bits = new UInt32[ ((source.Length * 6) + 31) >> 5];
|
||||
big_parse(bits, bits.Length, source, 16);
|
||||
return new BigInteger(bits);
|
||||
}
|
||||
|
||||
public static BigInteger FromHexString(string hex)
|
||||
{
|
||||
hex = hex.ToUpper();
|
||||
int length = (hex.Length+7) >> 3;
|
||||
UInt32[] bits = new uint[length];
|
||||
int n;
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
UInt32[] bits = new UInt32[ ((hex.Length * 6) + 31) >> 5];
|
||||
big_parse(bits, bits.Length, hex, 16);
|
||||
return new BigInteger(bits);
|
||||
}
|
||||
|
||||
|
@ -260,6 +306,645 @@ namespace ln.biginteger
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToString() => ToHexString();
|
||||
public string ToString(int radix)
|
||||
{
|
||||
if (IsZero)
|
||||
return "0";
|
||||
|
||||
UInt32[] r;
|
||||
UInt32[] v = (UInt32[])bits.Clone();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (Sign < 0)
|
||||
big_twos(v, v.Length);
|
||||
|
||||
while (big_cmp(v, v.Length, Zero.bits, Zero.bits.Length)!=0)
|
||||
{
|
||||
r = new UInt32[]{ (UInt32)radix };
|
||||
big_divmod(v, v.Length, r, r.Length);
|
||||
if (r[0] < 10)
|
||||
sb.Append((char)('0' + r[0]));
|
||||
else
|
||||
sb.Append((char)(55 + r[0]) );
|
||||
}
|
||||
|
||||
if (Sign < 0)
|
||||
sb.Append('-');
|
||||
|
||||
char[] chs = new char[sb.Length];
|
||||
sb.CopyTo(0,chs,0,sb.Length);
|
||||
Array.Reverse(chs);
|
||||
return new string(chs);
|
||||
}
|
||||
|
||||
|
||||
// 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 ***/
|
||||
|
||||
|
||||
|
||||
// public BigInteger(UInt32[] value)
|
||||
|
@ -866,31 +1551,47 @@ namespace ln.biginteger
|
|||
|
||||
|
||||
/*** Native Implementations ***/
|
||||
[DllImport("libbigint")]
|
||||
[DllImport("bigint")]
|
||||
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);
|
||||
/***
|
||||
big_get_bitlength() returns the number of bits needed to represent this value including the sign bit
|
||||
***/
|
||||
[DllImport("bigint")]
|
||||
public static extern Int32 big_get_bitlength(UInt32[] bits, Int32 length);
|
||||
public static Int32 big_get_bitlength(UInt32[] bits) => big_get_bitlength( bits, bits.Length );
|
||||
|
||||
[DllImport("libbigint")]
|
||||
[DllImport("bigint")]
|
||||
public static extern Int32 big_parse(UInt32[] op, Int32 length, String source, Int32 radix);
|
||||
// [DllImport("bigint")]
|
||||
// public static extern Int32 big_log2(UInt32[] bits, Int32 length);
|
||||
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_add(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
|
||||
public static void big_add(UInt32[] op_a, UInt32[] op_b) => big_add( op_a, op_a.Length, op_b, op_b.Length );
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_sub(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
|
||||
public static void big_sub(UInt32[] op_a, UInt32[] op_b) => big_sub( op_a, op_a.Length, op_b, op_b.Length );
|
||||
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_twos(UInt32[] bits, Int32 length);
|
||||
[DllImport("libbigint")]
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_shl(UInt32[] bits, Int32 length, Int32 n);
|
||||
[DllImport("libbigint")]
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_shr(UInt32[] bits, Int32 length, Int32 n);
|
||||
|
||||
|
||||
[DllImport("libbigint")]
|
||||
[DllImport("bigint")]
|
||||
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")]
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_smul(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
|
||||
public static void big_smul(UInt32[] op_a, UInt32[] op_b) => big_smul( op_a, op_a.Length, op_b, op_b.Length);
|
||||
[DllImport("bigint")]
|
||||
public static extern void big_divmod(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b);
|
||||
public static void big_divmod(UInt32[] op_a, UInt32[] op_b) => big_divmod( op_a, op_a.Length, op_b, op_b.Length);
|
||||
|
||||
|
||||
private int max(int a,int b) => a > b ? a : b;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="libbigint.so">
|
||||
<Content Include="libbigint.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
Loading…
Reference in New Issue