提交 2e7afa6a 编写于 作者: 饶先宏's avatar 饶先宏

202105270622

上级 a9b1f348
......@@ -73,7 +73,7 @@ typedef struct sIBigNumber {
int (*AssignStr)(HOBJECT object, const char* str, const char** nstr);
int (*Clone)(HOBJECT object, HOBJECT src);
int (*CloneSubBits)(HOBJECT object, HOBJECT src, int from, int width);
int (*CloneSubBits)(HOBJECT object, HOBJECT src, int from, int width, int signexpand);
int (*Assign)(HOBJECT object, HOBJECT src);
int (*AssignSubBits)(HOBJECT object, HOBJECT src, int from, int width);
int (*AssignU)(HOBJECT object, HOBJECT src);
......@@ -168,7 +168,7 @@ typedef struct sIBigNumber {
static int _obj##_bn_AssignUint64(HOBJECT object, unsigned long long value); \
static int _obj##_bn_AssignStr(HOBJECT object, const char* str, const char** nstr); \
static int _obj##_bn_Clone(HOBJECT object, HOBJECT src); \
static int _obj##_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width); \
static int _obj##_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width, int signexpand); \
static int _obj##_bn_Assign(HOBJECT object, HOBJECT src); \
static int _obj##_bn_AssignSubBits(HOBJECT object, HOBJECT src, int from, int width); \
static int _obj##_bn_AssignU(HOBJECT object, HOBJECT src); \
......
......@@ -271,7 +271,7 @@ static int bigint_bn_GetInt64(HOBJECT object, long long* pvalue)
return 0;
}
static int bigint_bn_GetUint32(HOBJECT object, int* pvalue)
static int bigint_bn_GetUint32(HOBJECT object, unsigned int* pvalue)
{
sBigInteger* pobj;
int width;
......@@ -285,7 +285,7 @@ static int bigint_bn_GetUint32(HOBJECT object, int* pvalue)
return 0;
}
static int bigint_bn_GetUint64(HOBJECT object, long long* pvalue)
static int bigint_bn_GetUint64(HOBJECT object, unsigned long long* pvalue)
{
sBigInteger* pobj;
int width;
......@@ -538,13 +538,16 @@ static int bigint_bn_Clone(HOBJECT object, HOBJECT src)
return 0;
}
static int bigint_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width)
static int bigint_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width, int signexpand)
{
if (from < 0 || width <= 0)
return -1;
bigint_bn_SetWidth(object, width, 0);
bigint_bn_SHR(object, src, from);
bigint_bn_SetWidth(object, width, 0);
if (signexpand)
bigint_bn_SAR(object, src, from);
else
bigint_bn_SHR(object, src, from);
bigint_bn_SetWidth(object, width, signexpand);
return 0;
}
......@@ -561,7 +564,7 @@ static int bigint_bn_AssignSubBits(HOBJECT object, HOBJECT src, int from, int wi
{
int objwidth;
objwidth = bigint_bn_GetWidth(object);
bigint_bn_CloneSubBits(object, src, from, width);
bigint_bn_CloneSubBits(object, src, from, width, 1);
bigint_bn_SetWidth(object, objwidth, 1);
return 0;
}
......@@ -579,7 +582,7 @@ static int bigint_bn_AssignSubBitsU(HOBJECT object, HOBJECT src, int from, int w
{
int objwidth;
objwidth = bigint_bn_GetWidth(object);
bigint_bn_CloneSubBits(object, src, from, width);
bigint_bn_CloneSubBits(object, src, from, width, 0);
bigint_bn_SetWidth(object, objwidth, 0);
return 0;
}
......@@ -606,13 +609,11 @@ static int bigint_bn_AddInt32(HOBJECT object, HOBJECT src, int value)
v = 0;
if (value < 0)
v = CELL_MASK;
while (temp != 0) {
if (ind >= pobj->buflen)
break;
while (ind < pobj->buflen) {
temp += v;
if (0 != objectCall2(numsrc, GetBits32, ind, &vs))
vs =
temp += pobj->buf[ind];
vs = CELL_MASK;
temp += vs;
pobj->buf[ind] = temp & CELL_MASK;
temp >>= CELL_WIDTH;
ind++;
......@@ -627,7 +628,7 @@ static int bigint_bn_SubInt32(HOBJECT object, HOBJECT src, int value)
static int bigint_bn_MulInt32(HOBJECT object, HOBJECT src, int value)
{
sBigInteger** temp;
IBigNumber ** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignInt32(temp, value);
bigint_bn_Mul(object, src, temp);
......@@ -637,7 +638,7 @@ static int bigint_bn_MulInt32(HOBJECT object, HOBJECT src, int value)
static int bigint_bn_DivInt32(HOBJECT object, HOBJECT src, int value)
{
sBigInteger** temp;
IBigNumber** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignInt32(temp, value);
bigint_bn_Div(object, src, temp);
......@@ -647,7 +648,7 @@ static int bigint_bn_DivInt32(HOBJECT object, HOBJECT src, int value)
static int bigint_bn_ModInt32(HOBJECT object, HOBJECT src, int value)
{
sBigInteger** temp;
IBigNumber** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignInt32(temp, value);
bigint_bn_Mod(object, src, temp);
......@@ -659,17 +660,25 @@ static int bigint_bn_AddUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
unsigned long long temp;
int ind;
unsigned int vs, widthsrc;
sBigInteger* pobj;
IBigNumber** numsrc;
pobj = (sBigInteger*)objectThis(object);
temp = pobj->buf[0];
temp += value;
if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&numsrc))
return -1;
widthsrc = objectCall0(numsrc, GetWidth);
objectCall2(numsrc, SetWidth, widthsrc, 0);
bigint_bn_SetWidth(object, pobj->width, 0);
objectCall2(numsrc, GetBits32, 0, &vs);
temp = vs;
temp += *(unsigned int*)&value;
pobj->buf[0] = temp & CELL_MASK;
temp >>= CELL_WIDTH;
ind = 1;
while (temp != 0) {
if (ind >= pobj->buflen)
break;
temp += pobj->buf[ind];
while (ind < pobj->buflen) {
if (0 != objectCall2(numsrc, GetBits32, ind, &vs))
vs = 0;
temp += vs;
pobj->buf[ind] = temp & CELL_MASK;
temp >>= CELL_WIDTH;
ind++;
......@@ -679,41 +688,15 @@ static int bigint_bn_AddUint32(HOBJECT object, HOBJECT src, unsigned int value)
static int bigint_bn_SubUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
unsigned long long temp;
int ind;
unsigned int v;
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
temp = pobj->buf[0];
v = 0;
/*如果不够,就向前借位*/
if (temp < value) {
v = CELL_MASK;
temp += 1ll << CELL_WIDTH;
}
temp -= value;
pobj->buf[0] = temp & CELL_MASK;
temp = v;
ind = 1;
while (temp != 0) {
if (ind >= pobj->buflen)
break;
v = 0;
if (temp < pobj->buf[ind]) {
v = CELL_MASK;
temp += 1ll << CELL_WIDTH;
}
temp -= pobj->buf[ind];
pobj->buf[ind] = temp & CELL_MASK;
temp = v;
ind++;
}
bigint_bn_AssignUint32(object, value);
bigint_bn_Neg(object, object);
bigint_bn_AddUint32(object, object, src);
return 0;
}
static int bigint_bn_MulUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
sBigInteger** temp;
IBigNumber** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignUint32(temp, value);
bigint_bn_MulU(object, src, temp);
......@@ -723,7 +706,7 @@ static int bigint_bn_MulUint32(HOBJECT object, HOBJECT src, unsigned int value)
static int bigint_bn_DivUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
sBigInteger** temp;
IBigNumber** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignUint32(temp, value);
bigint_bn_DivU(object, src, temp);
......@@ -733,7 +716,7 @@ static int bigint_bn_DivUint32(HOBJECT object, HOBJECT src, unsigned int value)
static int bigint_bn_ModUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
sBigInteger** temp;
IBigNumber** temp;
temp = bigintegerCreate(32);
bigint_bn_AssignUint32(temp, value);
bigint_bn_ModU(object, src, temp);
......@@ -741,7 +724,7 @@ static int bigint_bn_ModUint32(HOBJECT object, HOBJECT src, unsigned int value)
return 0;
}
static int bigint_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1)
static int bigint_bn_AddFunc(HOBJECT object, HOBJECT src0, HOBJECT src1, int signexpand)
{
unsigned long long temp;
sBigInteger* pobj;
......@@ -761,10 +744,16 @@ static int bigint_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1)
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, 1);
objectCall2(psrc0, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc0, SetWidth, widthsrc0, signexpand);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, 1);
objectCall2(psrc1, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc1, SetWidth, widthsrc1, signexpand);
}
temp = 0;
for (i = 0; i < pobj->buflen; i++) {
......@@ -778,16 +767,21 @@ static int bigint_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1)
}
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 1);
objectCall2(psrc0, SetWidth, widthsrc0, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 1);
objectCall2(psrc1, SetWidth, widthsrc1, 0);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
}
static int bigint_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
return bigint_bn_AddFunc(object, src0, src1, 1);
}
static int bigint_bn_Sub(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
if (EIID_OK != bigint_bn_Neg(object, src1))
......@@ -795,7 +789,7 @@ static int bigint_bn_Sub(HOBJECT object, HOBJECT src0, HOBJECT src1)
return bigint_bn_Add(object, src0, object);
}
static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
static int bigint_bn_MulFunc(HOBJECT object, HOBJECT src0, HOBJECT src1, int signexpand)
{
sBigInteger* pobj;
IBigNumber** psrc0;
......@@ -815,10 +809,16 @@ static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, 1);
objectCall2(psrc0, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc0, SetWidth, widthsrc0, signexpand);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, 1);
objectCall2(psrc1, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc1, SetWidth, widthsrc1, signexpand);
}
pobj->buflen = (pobj->width + CELL_WIDTH - 1) / CELL_WIDTH;
if (pobj->buflen < 2)
......@@ -839,9 +839,7 @@ static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
addin = 0;
objectCall2(psrc0, GetBits32, i, &m0s);
m0 = m0s;
for (j = 0; j < pobj->buflen; j++) {
if (i + j >= pobj->buflen)
break;
for (j = 0; j < pobj->buflen - i; j++) {
objectCall2(psrc1, GetBits32, j, &m1s);
m1 = m1s;
m1 = m0 * m1 + addin + buf[i+j];
......@@ -863,6 +861,11 @@ static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
return 0;
}
static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
return bigint_bn_MulFunc(object, src0, src1, 1);
}
static int bigint_bn_Div(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
sBigInteger* pobj;
......@@ -881,49 +884,7 @@ static int bigint_bn_Mod(HOBJECT object, HOBJECT src0, HOBJECT src1)
static int bigint_bn_AddU(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
unsigned long long temp;
sBigInteger* pobj;
IBigNumber** psrc0;
IBigNumber** psrc1;
int widthobj, widthsrc0, widthsrc1;
int i;
pobj = (sBigInteger*)objectThis(object);
if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
return -1;
}
if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
objectRelease(psrc0);
return -1;
}
widthobj = pobj->width;
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, 0);
}
temp = 0;
for (i = 0; i < pobj->buflen; i++) {
unsigned int src0value, src1value;
objectCall2(psrc0, GetBits32, i, &src0value);
objectCall2(psrc1, GetBits32, i, &src1value);
temp += src0value;
temp += src1value;
pobj->buf[i] = temp & CELL_MASK;
temp >>= CELL_WIDTH;
}
bigint_bn_SetWidth(object, widthobj, 0);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 0);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
return bigint_bn_AddFunc(object, src0, src1, 0);
}
static int bigint_bn_SubU(HOBJECT object, HOBJECT src0, HOBJECT src1)
......@@ -935,70 +896,7 @@ static int bigint_bn_SubU(HOBJECT object, HOBJECT src0, HOBJECT src1)
static int bigint_bn_MulU(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
sBigInteger* pobj;
IBigNumber** psrc0;
IBigNumber** psrc1;
unsigned int* buf;
int widthobj, widthsrc0, widthsrc1;
int i, j;
pobj = (sBigInteger*)objectThis(object);
if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
return -1;
}
if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
objectRelease(psrc0);
return -1;
}
widthobj = pobj->width;
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, 0);
}
pobj->buflen = (pobj->width + CELL_WIDTH - 1) / CELL_WIDTH;
if (pobj->buflen < 2)
pobj->buflen = 2;
buf = (unsigned int*)malloc(pobj->buflen * CELL_WIDTH / 8);
if (buf == NULL) {
objectRelease(psrc0);
objectRelease(psrc1);
return -1;
}
for (i = 0; i < pobj->buflen; i++)
buf[i] = 0;
for (i = 0; i < pobj->buflen; i++) {
unsigned long long addin;
unsigned long long m0, m1;
unsigned int m0s, m1s;
addin = 0;
objectCall2(psrc0, GetBits32, i, &m0s);
m0 = m0s;
for (j = 0; j < pobj->buflen; j++) {
if (i + j >= pobj->buflen)
break;
objectCall2(psrc1, GetBits32, j, &m1s);
m1 = m1s;
m1 = m0 * m1 + addin + buf[i + j];
buf[i + j] = m1 & CELL_MASK;
addin = m1 >> CELL_WIDTH;
}
}
free(pobj->buf);
pobj->buf = buf;
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 1);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 1);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
return bigint_bn_MulFunc(object, src0, src1, 0);
}
static int bigint_bn_DivU(HOBJECT object, HOBJECT src0, HOBJECT src1)
......@@ -1529,58 +1427,181 @@ static int bigint_bn_NotL(HOBJECT object)
static int bigint_bn_And(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
int signexpand = 1;
sBigInteger* pobj;
IBigNumber** psrc0;
IBigNumber** psrc1;
int widthobj, widthsrc0, widthsrc1;
int i;
pobj = (sBigInteger*)objectThis(object);
if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
return -1;
}
if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
objectRelease(psrc0);
return -1;
}
widthobj = pobj->width;
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc0, SetWidth, widthsrc0, signexpand);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc1, SetWidth, widthsrc1, signexpand);
}
for (i = 0; i < pobj->buflen; i++) {
unsigned int src0value, src1value;
objectCall2(psrc0, GetBits32, i, &src0value);
objectCall2(psrc1, GetBits32, i, &src1value);
pobj->buf[i] = src0value & src1value;
}
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 0);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
}
static int bigint_bn_Or(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
int signexpand = 1;
sBigInteger* pobj;
sBigInteger* psrc;
/*
IBigNumber** psrc0;
IBigNumber** psrc1;
int widthobj, widthsrc0, widthsrc1;
int i;
pobj = (sBigInteger*)objectThis(object);
if (!objectIsClass(src, CLSID_BIGINTEGER)) {
if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
return -1;
}
psrc = (sBigInteger*)objectThis(src);
for (i = 0; i < pobj->buflen && i < psrc->buflen; i++) {
pobj->buf[i] |= psrc->buf[i];
}*/
if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
objectRelease(psrc0);
return -1;
}
widthobj = pobj->width;
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc0, SetWidth, widthsrc0, signexpand);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc1, SetWidth, widthsrc1, signexpand);
}
for (i = 0; i < pobj->buflen; i++) {
unsigned int src0value, src1value;
objectCall2(psrc0, GetBits32, i, &src0value);
objectCall2(psrc1, GetBits32, i, &src1value);
pobj->buf[i] = src0value | src1value;
}
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 0);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 0);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
}
static int bigint_bn_Xor(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
int signexpand = 1;
sBigInteger* pobj;
sBigInteger* psrc;
/*
IBigNumber** psrc0;
IBigNumber** psrc1;
int widthobj, widthsrc0, widthsrc1;
int i;
pobj = (sBigInteger*)objectThis(object);
if (!objectIsClass(src, CLSID_BIGINTEGER)) {
if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
return -1;
}
psrc = (sBigInteger*)objectThis(src);
for (i = 0; i < pobj->buflen && i < psrc->buflen; i++) {
pobj->buf[i] ^= psrc->buf[i];
if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
objectRelease(psrc0);
return -1;
}
for (; i < pobj->buflen; i++) {
pobj->buf[i] ^= 0;
widthobj = pobj->width;
widthsrc0 = objectCall0(psrc0, GetWidth);
widthsrc1 = objectCall0(psrc1, GetWidth);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc0, SetWidth, widthsrc0, signexpand);
}
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc1, SetWidth, widthsrc1, signexpand);
}
for (i = 0; i < pobj->buflen; i++) {
unsigned int src0value, src1value;
objectCall2(psrc0, GetBits32, i, &src0value);
objectCall2(psrc1, GetBits32, i, &src1value);
pobj->buf[i] = src0value ^ src1value;
}
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc0 < widthobj) {
objectCall2(psrc0, SetWidth, widthsrc0, 0);
}
*/
if (widthsrc1 < widthobj) {
objectCall2(psrc1, SetWidth, widthsrc1, 0);
}
objectRelease(psrc0);
objectRelease(psrc1);
return 0;
}
static int bigint_bn_Not(HOBJECT object, HOBJECT src)
{
int i;
int signexpand = 1;
sBigInteger* pobj;
/*
IBigNumber** psrc;
int widthobj, widthsrc;
int i;
pobj = (sBigInteger*)objectThis(object);
for (i = 0; i < pobj->buflen; i++)
pobj->buf[i] = ~pobj->buf[i];
*/
if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
return -1;
}
widthobj = pobj->width;
widthsrc = objectCall0(psrc, GetWidth);
if (widthsrc < widthobj) {
objectCall2(psrc, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc, SetWidth, widthsrc, signexpand);
}
for (i = 0; i < pobj->buflen; i++) {
unsigned int srcvalue;
objectCall2(psrc, GetBits32, i, &srcvalue);
pobj->buf[i] = ~srcvalue;
}
bigint_bn_SetWidth(object, widthobj, 1);
if (widthsrc < widthobj) {
objectCall2(psrc, SetWidth, widthsrc, 0);
}
objectRelease(psrc);
return 0;
}
......@@ -1588,6 +1609,7 @@ static int bigint_bn_uAnd(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
......@@ -1595,6 +1617,7 @@ static int bigint_bn_uAndNot(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
......@@ -1602,6 +1625,7 @@ static int bigint_bn_uOr(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
......@@ -1609,6 +1633,7 @@ static int bigint_bn_uOrNot(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
......@@ -1616,6 +1641,7 @@ static int bigint_bn_uXor(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
......@@ -1623,30 +1649,53 @@ static int bigint_bn_uXorNot(HOBJECT object, HOBJECT src)
{
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
NOTIMPL;
return 0;
}
static int bigint_bn_SHL(HOBJECT object, HOBJECT src, int bits)
{
sBigInteger* pobj;
int signexpand = 1;
IBigNumber** psrc;
int widthobj, widthsrc;
int ifrom, ito, i;
unsigned long long current, next;
pobj = (sBigInteger*)objectThis(object);
if (bits == 0)
return 0;
if (bits < 0)
return bigint_bn_SHR(object, src, -bits);
pobj = (sBigInteger*)objectThis(object);
if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
return -1;
}
widthobj = pobj->width;
widthsrc = objectCall0(psrc, GetWidth);
if (widthsrc < widthobj) {
objectCall2(psrc, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc, SetWidth, widthsrc, signexpand);
}
ito = bits / CELL_WIDTH;
bits -= ito * CELL_WIDTH;
ifrom = 0;
for (i = pobj->buflen-1; i>=0; i--) {
current = 0;
if (i >= ito) {
current = pobj->buf[i - ito];
unsigned int srcvalue;
objectCall2(psrc, GetBits32, i-ito, &srcvalue);
current = srcvalue;
current <<= CELL_WIDTH;
}
if (i >= ito+1) {
next = pobj->buf[i - ito -1];
unsigned int srcvalue;
objectCall2(psrc, GetBits32, i - ito - 1, &srcvalue);
next = srcvalue;
current |= next;
}
current >>= CELL_WIDTH - bits;
......@@ -1658,6 +1707,10 @@ static int bigint_bn_SHL(HOBJECT object, HOBJECT src, int bits)
static int bigint_bn_SHR(HOBJECT object, HOBJECT src, int bits)
{
sBigInteger* pobj;
int signexpand = 0;
IBigNumber** psrc;
unsigned int srcvalue;
int widthobj, widthsrc;
int bc;
int ifrom, ito, i, zerolen;
unsigned long long current, next;
......@@ -1666,26 +1719,41 @@ static int bigint_bn_SHR(HOBJECT object, HOBJECT src, int bits)
return 0;
if (bits < 0)
return bigint_bn_SHL(object, src, -bits);
if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
return -1;
}
widthobj = pobj->width;
widthsrc = objectCall0(psrc, GetWidth);
if (widthsrc < widthobj) {
objectCall2(psrc, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc, SetWidth, widthsrc, signexpand);
}
ito = 0;
ifrom = bits / CELL_WIDTH;
if (ifrom >= pobj->buflen) {
memset(pobj->buf, 0, pobj->buflen * (CELL_WIDTH/8));
if (bits >= widthsrc) {
for (i = 0;i<pobj->buflen;i++)
pobj->buf[i] = signexpand?CELL_MASK:0;
return 0;
}
bits -= ifrom * CELL_WIDTH;
if (ifrom+1 < pobj->buflen) {
current = pobj->buf[ifrom+1];
objectCall2(psrc, GetBits32, ifrom + 1, &srcvalue);
current = srcvalue;
current <<= CELL_WIDTH;
}
else {
current = 0;
}
current |= pobj->buf[ifrom];
objectCall2(psrc, GetBits32, ifrom, &srcvalue);
current |= srcvalue;
current >>= bits;
for (i = ifrom + 1; i < pobj->buflen-1; i++) {
pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
current >>= CELL_WIDTH;
next = pobj->buf[i + 1];
objectCall2(psrc, GetBits32, ifrom, &srcvalue);
next = srcvalue;
next <<= CELL_WIDTH-bits;
current |= next;
}
......@@ -1703,6 +1771,10 @@ static int bigint_bn_SAL(HOBJECT object, HOBJECT src, int bits)
static int bigint_bn_SAR(HOBJECT object, HOBJECT src, int bits)
{
sBigInteger* pobj;
int signexpand = 1;
IBigNumber** psrc;
unsigned int srcvalue;
int widthobj, widthsrc;
int bc, sign;
int ifrom, ito, i, zerolen;
unsigned long long current, next;
......@@ -1711,8 +1783,20 @@ static int bigint_bn_SAR(HOBJECT object, HOBJECT src, int bits)
return 0;
if (bits < 0)
return bigint_bn_SHL(object, src, -bits);
if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
return -1;
}
widthobj = pobj->width;
widthsrc = objectCall0(psrc, GetWidth);
if (widthsrc < widthobj) {
objectCall2(psrc, SetWidth, widthobj, signexpand);
}
else {
objectCall2(psrc, SetWidth, widthsrc, signexpand);
}
bc = pobj->width / CELL_WIDTH;
sign = pobj->buf[bc] & (1 << ((pobj->width-1) & (CELL_WIDTH - 1)));
objectCall2(psrc, GetBits32, bc, &srcvalue);
sign = srcvalue & (1 << ((pobj->width-1) & (CELL_WIDTH - 1)));
ito = 0;
ifrom = bits / CELL_WIDTH;
if (ifrom >= pobj->buflen) {
......@@ -1722,18 +1806,21 @@ static int bigint_bn_SAR(HOBJECT object, HOBJECT src, int bits)
}
bits -= ifrom * CELL_WIDTH;
if (ifrom + 1 < pobj->buflen) {
current = pobj->buf[ifrom + 1];
objectCall2(psrc, GetBits32, ifrom+1, &srcvalue);
current = srcvalue;
current <<= CELL_WIDTH;
}
else {
current = 0;
}
current |= pobj->buf[ifrom];
objectCall2(psrc, GetBits32, ifrom, &srcvalue);
current |= srcvalue;
current >>= bits;
for (i = ifrom + 1; i < pobj->buflen - 1; i++) {
pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
current >>= CELL_WIDTH;
next = pobj->buf[i + 1];
objectCall2(psrc, GetBits32, i + 1, &srcvalue);
next = srcvalue;
next <<= CELL_WIDTH - bits;
current |= next;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册