我读了一些十六进制数字,然后我想将它们转换为基数 2^64。不幸的是,由于这个数字不能存储在一个 int 中,似乎 GMP 中没有可以帮助我解决这个问题的函数。
还有另一种我完全想念的方法吗?
(程序是C语言)
我读了一些十六进制数字,然后我想将它们转换为基数 2^64。不幸的是,由于这个数字不能存储在一个 int 中,似乎 GMP 中没有可以帮助我解决这个问题的函数。
还有另一种我完全想念的方法吗?
(程序是C语言)
以 2^1 为基数的 10 是1010
二进制的1 0 1 0
以 2^2 为基数的 10 是22
二进制的10 10
以 2^3 为基数的 10 是12
二进制的001 010
以 2^4 为基数的 10 是A
二进制的1010
我试图向您展示的模式(以及其他人已经注意到的)是它们都具有相同的二进制表示。换句话说,如果您将您的数字转换为基数 256 ( char
s) 并将其写入文件或内存,您可以在基数 2^16(一次读取 2 个字节)或基数 2^32(4 个字节)中读取它一次),或者实际上是 2^anything。它将是相同的二进制表示(假设您的字节序正确)。所以要小心使用大端与小端并读为int64_t
.
需要明确的是,这仅适用于 2^n 的碱基。以 5 为底的 10 是20
二进制中的010 000
; 明显不同。但是如果你使用三进制,同样的原理也适用于 3^n,而在五进制 (?) 中它也适用于 5^n。
更新:你如何使用它:
有一些功能
无效转换(char *myBase16String,uint8_t *outputBase256);
我们假设采用以 16 为基数编码的字符串并生成一个无符号字符数组,其中每个字符都是以 256 为基数的一个单元,我们这样做:
uint8_t base2_8[8];
convert( "0123456789ABCDEF", base2_8 );
uint64_t base2_64[2];
base2_64[0] = (base2_8[0] << 24) | (base2_8[1] << 16) | (base2_8[2] << 8) | base2_8[3];
base2_64[1] = (base2_8[4] << 24) | (base2_8[5] << 16) | (base2_8[6] << 8) | base2_8[7];
// etc. You can do this in a loop, but make sure you know how long it is.
假设您的输入不是一个很好的 4 个字节的倍数:
uint8_t base2_8[6];
convert( "0123456789AB", base2_8 );
uint64_t base2_64[2];
base2_64[0] = (base2_8[0] << 8) | base2_8[1];
base2_64[1] = (base2_8[2] << 24) | (base2_8[3] << 16) | (base2_8[4] << 8) | base2_8[5];
稍微复杂一些,但仍然很容易自动化。
GMP 附带了stdio.h
适用于大量数字的扩展,请参阅格式化输入函数手册。
gmp_scanf
标准输入 ( )、文件 ( gmp_fscanf
) 或您已经读入内存 ( ) 的字符串有一些常用的风格gmp_sscanf
。