我正在研究一个项目,我需要对基数为256的数字进行计算。我正在读取文件的字节并将其存储在uint8_t
(又名unsigned char
或BYTE
)。支持的最大数字数据类型并不能满足我的项目需求。因此,字节数组的作用类似于自定义长度/大小数据类型(BigInt
)。
我现在需要对其执行算术,例如:-1, /2, %2
。
例如,这就是加法看起来如何展示我的数字应该如何工作:
9 + 1 = (10)
99 + 1 = (100)
255 + 1 = (1)+(0)<<8
255 + 2 = (1)+(1)<<8
注意:第一个是10,因为10个占据1个数字,而第三个是1 0,因为它占据2个数字。此外,我无法将它们转换为整数,因为我必须处理巨大的数字。
我正绞尽脑汁试图想办法在C中实现这一点,但无济于事。
到目前为止我的代码:
#include<stdio.h>
#include<string.h>
#include<stdint.h>
#include<stdlib.h>
typedef uint8_t BYTE;
BYTE buffer[1000000000];
void n(){
printf("\n");
}
int main()
{
uint32_t x;
x = 0;
int _len,y;
char * test = "test.bin";
FILE * inptr = fopen(test,"rb");
uint32_t i=0;
while(fread(&buffer[i],1,1,inptr));
}
答案 0 :(得分:3)
所以你有2个操作的强大功能,可以很容易地转换为位操作......对于这种无关紧要的事情,不需要bigint lib。假设你有数字
const int n=1000000000; // number size in bytes
BYTE x[n]; // number bytes let num[0] be LSW (least signifficant Word)
所涉及的操作是:
mod:y = x%2 = x&1
这是O(1)
BYTE y = x[0]&1;
结果是单个位,因此无需将其存储为bigint
div:y = x/2 = x>>1
这是O(n)
,结果也是bigint所以
int i;
BYTE y[n]; // result
BYTE cy; // carry flag
for (cy=0,i=n-1;i>=0;i--) // process all words from MSW to LSW
{
y[i] = ((x[i]>>1)&0x7F) | cy; // bitshifted word + last carry
cy = (x[i]<<7)&0x80; // carry is shifted out lsb of word shifted to msb position
}
dec:y=x-1
这是O(n)
,结果也是bigint所以
int i;
BYTE y[n]; // result
BYTE cy; // carry flag
for (cy=1,i=0;(i<n)&&(cy);i++) // process all words from LSW to MSW
{
y[i] = (x[i]-cy)&0xFF; // y[i] = sbc x[i],0
cy = (x[i]==0x00); // carry
}
希望我没有做出一些愚蠢的语法错误或者我直接将其编码到这里...
两个O(n)
操作都可以就地完成,您只需缓冲实际的x[i]
值或在x[i]
更改之前计算进位并缓冲旧进位
在你的情况下,我会使用32位(DWORD)或64位(QWORD)而不是8位(BYTE)来提高速度,因为大多数计算机上的 ALU 为32
或{无论如何{1}}位
如果您对实施更多bigint内容感兴趣,请参阅:
[编辑1] 64
首先为MSW
dec
和就地
int i;
BYTE y[n]; // result
BYTE cy; // carry flag
for (cy=1,i=n-1;(i>=0)&&(cy);i--) // process all words from LSW to MSW
{
y[i] = (x[i]-cy)&0xFF; // y[i] = sbc x[i],0
cy = (x[i]==0x00); // carry
}