From 2e7afa6a3bb85c5f0c6c53d44b6b2e223600007e Mon Sep 17 00:00:00 2001 From: m0_56903617 Date: Thu, 27 May 2021 06:22:54 +0800 Subject: [PATCH] 202105270622 --- bignumber/include/bignumber.h | 4 +- bignumber/src/bignumber.c | 497 ++++++++++++++++++++-------------- 2 files changed, 294 insertions(+), 207 deletions(-) diff --git a/bignumber/include/bignumber.h b/bignumber/include/bignumber.h index 2386cb9..6ebc99a 100644 --- a/bignumber/include/bignumber.h +++ b/bignumber/include/bignumber.h @@ -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); \ diff --git a/bignumber/src/bignumber.c b/bignumber/src/bignumber.c index 57faea5..29582e2 100644 --- a/bignumber/src/bignumber.c +++ b/bignumber/src/bignumber.c @@ -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;ibuflen;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; } -- GitLab