提交 48e5d8bb 编写于 作者: 饶先宏's avatar 饶先宏

202105202144

上级 5a685b4d
......@@ -50,7 +50,7 @@ DEFINE_GUID(IID_BIGNUMBER, 0x80dc5305, 0x1ca6, 0x4678, 0xbf, 0xc3, 0xd0, 0x1b, 0
typedef struct sIBigNumber {
OBJECT_INTERFACE
int (*GetBitsCount)(HOBJECT object);
int (*SetBitsCount)(HOBJECT object, int count);
int (*GetInt)(HOBJECT object, int* pvalue);
int (*GetInt64)(HOBJECT object, long long* pvalue);
int (*GetFloat)(HOBJECT object, float* pvalue);
......@@ -93,6 +93,7 @@ typedef struct sIBigNumber {
#define BIGNUMBER_FUNCDECLARE(_obj, _clsid, _localstruct) \
static int _obj##_bn_GetBitsCount(HOBJECT object); \
static int _obj##_bn_SetBitsCount(HOBJECT object, int count); \
static int _obj##_bn_GetInt(HOBJECT object, int* pvalue); \
static int _obj##_bn_GetInt64(HOBJECT object, long long* pvalue); \
static int _obj##_bn_GetFloat(HOBJECT object, float* pvalue); \
......@@ -125,6 +126,7 @@ typedef struct sIBigNumber {
static const IBigNumber _obj##_bn_interface = { \
INTERFACE_HEADER(_obj, IBigNumber, _localstruct) \
_obj##_bn_GetBitsCount, \
_obj##_bn_SetBitsCount, \
_obj##_bn_GetInt, \
_obj##_bn_GetInt64, \
_obj##_bn_GetFloat, \
......
......@@ -91,13 +91,13 @@ static int actualwidth(unsigned int n)
{
unsigned int c = 1;
int ret = 1;
if (c & 0x80000000)
if (n & 0x80000000)
return 32;
while (c < n) {
while (c <= n) {
c <<= 1;
ret++;
}
return ret;
return ret-1;
}
static void bigintDestroy(HOBJECT object)
......@@ -134,6 +134,25 @@ static int bigint_bn_GetBitsCount(HOBJECT object)
return 0;
}
static int bigint_bn_SetBitsCount(HOBJECT object, int count)
{
int i, bc;
sBigInteger* pobj;
pobj = (sBigInteger*)objectThis(object);
if (count <= 0) {
memset(pobj->buf, 0, pobj->buflen * 4);
return 0;
}
bc = bigint_bn_GetBitsCount(pobj);
if (count >= bc)
return 0;
for (i = (count+31) / 32; i < pobj->buflen; i++) {
pobj->buf[i] = 0;
}
pobj->buf[count / 32] &= 0xffffffff >> (32 - (count & 31));
return 0;
}
static int bigint_bn_GetInt(HOBJECT object, int* pvalue)
{
sBigInteger* pobj;
......@@ -180,6 +199,10 @@ static int bigint_bn_GetStr(HOBJECT object, int base, char* str, int buflen)
pobj = (sBigInteger*)objectThis(object);
str[0] = 0;
bc = bigint_bn_GetBitsCount(object);
if (bc == 0) {
strcpy(str, "0");
return 0;
}
sprintf(str, "%d'h", bc);
i = ((bc + 31) / 32) - 1;
ac = actualwidth(pobj->buf[i]);
......@@ -554,21 +577,79 @@ static int bigint_bn_Div(HOBJECT object, HOBJECT src)
static int bigint_bn_SHL(HOBJECT object, int bits)
{
sBigInteger* pobj;
int bc;
int bc, blen;
int ifrom, ito, i;
unsigned long long current, next;
unsigned int* buf;
pobj = (sBigInteger*)objectThis(object);
if (bits == 0)
return 0;
if (bits < 0)
return bigint_bn_SHR(object, -bits);
bc = bigint_bn_GetBitsCount(object);
while (bc + bits > pobj->buflen * 32) {
if (bigint_expandbuf(pobj) != 0)
return -1;
blen = (bc + bits + 31) / 32;
buf = (unsigned int*)malloc(blen * 4);
if (buf == NULL)
return -1;
ito = bits / 32;
if (ito > 0) {
memset(buf, 0, ito * 4);
}
/* fixed me */
bits -= ito * 32;
ifrom = 0;
current = pobj->buf[0];
current <<= bits;
for (i = 1; i < (bc + 31) / 32; i++) {
buf[ito++] = (unsigned int)(current & 0xffffffff);
current >>= 32;
next = pobj->buf[i];
next <<= bits;
current |= next;
}
buf[ito] = (unsigned int)(current & 0xffffffff);
free(pobj->buf);
pobj->buf = buf;
pobj->buflen = blen;
return 0;
}
static int bigint_bn_SHR(HOBJECT object, int bits)
{
{
sBigInteger* pobj;
int bc;
int ifrom, ito, i, zerolen;
unsigned long long current, next;
pobj = (sBigInteger*)objectThis(object);
if (bits == 0)
return 0;
if (bits < 0)
return bigint_bn_SHL(object, -bits);
ito = 0;
ifrom = bits / 32;
if (ifrom >= pobj->buflen) {
memset(pobj->buf, 0, pobj->buflen * 4);
return 0;
}
bits -= ifrom * 32;
if (ifrom+1 < pobj->buflen) {
current = pobj->buf[ifrom+1];
current <<= 32;
}
else {
current = 0;
}
current |= pobj->buf[ifrom];
current >>= bits;
for (i = ifrom + 1; i < pobj->buflen-1; i++) {
pobj->buf[ito++] = (unsigned int)(current & 0xffffffff);
current >>= 32;
next = pobj->buf[i + 1];
next <<= 32-bits;
current |= next;
}
pobj->buf[ito++] = (unsigned int)(current & 0xffffffff);
while (ito < pobj->buflen)
pobj->buf[ito++] = 0;
return 0;
}
......
......@@ -34,11 +34,11 @@
#include "object.h"
#include "bignumber.h"
const char* testnumber = "43, 4, 128'b0101011111011010100011000101010101010100010101010101010001, 'h94397afc4343, 5'd98";
const char* testnumber = "77'h4137489137419837408139048137908791875841983274987132, 43, 4, 128'b0101011111011010100011000101010101010100010101010101010001, 'h94397afc4343, 5'd98";
int main(int argc, char* argv[])
{
char buf[128];
char buf[256];
IBigNumber** bignumber = bigintegerCreate();
const char* nstr = testnumber;
const char* lstr = testnumber;
......@@ -47,5 +47,11 @@ int main(int argc, char* argv[])
printf("%s=%s, \nnext=%s\n", lstr, buf, nstr);
lstr = nstr;
}
objectCall2(bignumber, AssignStr, testnumber, &nstr);
objectCall3(bignumber, GetStr, 16, buf, 256);
printf("n=%s\n", buf);
objectCall1(bignumber, SetBitsCount, 9);
objectCall3(bignumber, GetStr, 16, buf, 256);
printf("n<<68=%s\n", buf);
return 0;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册