我在结果中得到了大的十六进制字符串,将其转换为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
如果这样做(并使用二进制累加器(,求和后的"压缩"将很快导致整数除法(可以简单地通过移位和重复减法来完成(无论如何。。。