如何在C中将大的HEX字符串转换为INT



我在结果中得到了大的十六进制字符串,将其转换为int,I可能超过10^30,并且我转换为十六进制。我需要求和(3个十六进制字符串(并去掉最后12个数字。

十六进制示例";00000000000000000000000000000000bd4c61f945644cf099d41ab8a0b2ac5d25333835"00000000000000000000000000000000000000f32f5908b7f3c000"0000000000000000000000000000000000000000 e969cd49be4000";。我需要对它们求和,并将结果输入int。谢谢

我"制成";有两个函数,它们可以工作,但我认为可能会更好,而且它们不会转换为正常的整数


// convert hex to unsigned char decimal
unsigned char div10(unsigned char *hex, unsigned size)
{
unsigned rem = 0;
for(int i = 0; i < size; i++)
{
unsigned n = rem * 256 + hex[i];
hex[i] = n / 10;
rem = n % 10;
}
return rem;
}


unsigned char hex_to_dec_summer(char *local){
unsigned char result[32]={0};
unsigned char output[18]={};

char input[64];
strcpy(input, local);

unsigned char hexnr[sizeof(input)/2]={}; 
for (int i=0; i<sizeof(input)/2; i++) {
sscanf(&input[i*2], "%02xd", &hexnr[i]);
}


unsigned char hexzero[32] = {0};
unsigned i = 0;
while(memcmp(hexnr, hexzero, sizeof(hexnr)) != 0 && i < sizeof(result))
{
result[sizeof(result) - i - 1] = div10(hexnr, sizeof(hexnr));
i++;
}
printf("n");

for(unsigned j = 0; j < sizeof output; j++)
{
output[j]=result[j];
printf("%d", output[j]);
}
output[18]='';
}

我知道蟒蛇是怎么做的3->int(hex_number, 16)/(10**12)-类似,但我需要它在c 中

这类事情在Python中如此容易工作的原因是,不同寻常的是,Python本机支持任意精度整数。

包括C语言在内的大多数语言对其原生类型使用固定大小。要执行任意精度的运算,通常需要一个单独的库,例如GMP。

以下是使用GMP解决问题的基本示例:

#include <stdio.h>
#include <gmp.h>
char *inputs[] = {
"000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835",
"000000000000000000000000000000000000000000000000f32f5908b7f3c000",
"00000000000000000000000000000000000000000000000000e969cd49be4000"
};
int main()
{
char outstr[100];
mpz_t x; mpz_init(x);
mpz_t y; mpz_init(y);
mpz_t sum; mpz_init(sum);
mpz_t ten; mpz_init_set_si(ten, 10);
mpz_t fac; mpz_init(fac);
mpz_pow_ui(fac, ten, 12);        /* fac = 10**12 */
int i;
for(i = 0; i < 3; i++) {
mpz_set_str(x, inputs[i], 16);
mpz_tdiv_q(y, x, fac);
mpz_add(sum, sum, y);        /* sum += x / fac */
}
printf("%sn", mpz_get_str(outstr, 10, sum));
}

这段代码有点冗长,因为任意精度整数(即mpz_t类型的变量(都有非常重要的内存分配要求,而且对它们所做的一切都需要显式的函数调用。(在像C++这样支持面向对象编程的语言中,使用这样的扩展类型会方便得多。(

要编译这个,你需要安装GMP。在我的机器上,我使用

cc testprog.c -lgmp

运行时,此程序打印

1080702647035076263416932216315997551

或者,如果我在最后一行中将10改为16,它将打印d022c1183a2720991b1fea332a6d6f

无论你除以1012然后求和,还是求和然后除以,都会有细微的区别。要求和再除法,可以去掉循环中的线mpz_tdiv_q(y, x, fac),将mpz_add(sum, sum, y)更改为mpz_add(sum, sum, x),并添加线

mpz_tdiv_q(sum, sum, fac);

在循环外,就在打印之前。

将两个字符串的(在本例中为十六进制(数字相加是相当简单的。

这并不试图成为";"最优";,但它确实给出了一个和(作为十六进制数字的字符串(。vals[0]充当累加器。

当OP阐明了";我需要求和(3个十六进制字符串(并去除最后12个数字";,这个答案可以推广。

如果需要更高的速度,累加器可以被分配并用作uint8_t的数组(保存转换回ASCII十六进制直到最终总数可用。(此外,将ASCII十六进制转换为"0-F"的LUT可以是"二进制"(不需要减去ASCII字符值(

不管怎样。。。

#include <stdio.h>
char *vals[] = {
"000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835",
"000000000000000000000000000000000000000000000000f32f5908b7f3c000",
"00000000000000000000000000000000000000000000000000e969cd49be4000",
};
char *frmHex =
"................................................0000000000......"
".777777..........................WWWWWW.........................";
char *tohex = "0123456789ABCDEF";
void addTo( char *p0, char *p1 ) {
printf( "  %sn+ %sn", p0, p1 );
char *px = p0 + strlen( p0 ) - 1;
char *py = p1 + strlen( p1 ) - 1;
for( int carry = 0; px >= p0 && py >= p1; px--, py-- ) {
int val = *px - frmHex[ *px ] + *py - frmHex[ *py ] + carry;
carry = val / 0x10; *px = tohex[ val % 0x10 ];
}
printf( "= %snn", p0 );
}
int main() {
addTo( vals[ 0 ], vals[ 1 ] );
addTo( vals[ 0 ], vals[ 2 ] );
return 0;
}

输出

000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835
+ 000000000000000000000000000000000000000000000000f32f5908b7f3c000
= 000000000000000000000000BD4C61F945644CF099D41AB993DA83CE8A46F835
000000000000000000000000BD4C61F945644CF099D41AB993DA83CE8A46F835
+ 00000000000000000000000000000000000000000000000000e969cd49be4000
= 000000000000000000000000BD4C61F945644CF099D41AB994C3ED9BD4053835

如果这样做(并使用二进制累加器(,求和后的"压缩"将很快导致整数除法(可以简单地通过移位和重复减法来完成(无论如何。。。

最新更新