2013-03-16 30 views
0

我读了一些十六进制数字,然后我想将它们转换为基地2^64。不幸的是,因为这个数字不能存储在int中,所以似乎GMP中没有可以帮助我解决这个问题的函数。基地16基地2^64转换在GMP

有没有另一种方法可以做到这一点,我完全失踪了?

(该程序是在C)

+0

你在做C吗? – teppic 2013-03-16 22:50:46

+3

基数16与基数2^4相同。你意识到一个2^64的数字只包含16个2^4的数字,对吗? – Gabe 2013-03-16 22:51:03

+0

是的,我正在C做(可能应该提到这一点)。无论如何,2^64 = 16 * 2^4这个事实是怎么帮助的? – 2013-03-16 22:59:16

回答

1

在基座2 10^1是1010这在二进制是1 0 1 0

10在基体2^2是22这在二进制是10 10

10在基体2^3是12这在二进制是001 010

在基座2 10^4 A这在二进制是1010

我试图告诉你(和其他人已经注意到)的模式是它们都具有相同的二进制表示形式。换句话说,如果您将您的号码转换为256(char s)并将其写入文件或内存,则可以以2^16(每次读取2个字节)或2^32(4字节在一次),或者实际上2 ^任何东西。这将是相同的二进制表示(假设你的endians正确)。所以要注意大码和小码,并且请注意int64_t

要清楚的是,这只适用于2^n的碱基。基数5中的10是20,其在二进制中是010 000;明显不同。但是如果你使用trinary,同样的原则适用于3^n,而在五元组(?)它适用于5^n。

更新:你怎么可以这样做:

随着一些功能

无效转换(字符* myBase16String,uint8_t * outputBase256);

我们假设需要在基座16编码的字符串,并产生无符号字符数组,其中每个字符为单位在基座256中,我们这样做:

uint8_t base2_8[8]; 
convert("ABCDEF", 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("AB", 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]; 

稍微复杂一些,但仍然很容易实现自动化。

+0

我很欣赏这个解释(其实很有意思),但我怎样才能在mpz_get_str中使用这个? – 2013-03-16 23:21:48

+0

我不知道你正在使用的库的细节,但基本的想法是将你的编号转换为一些n的基本2^n(如果可能的话,8将是很好的),然后循环输出编写它作为字节到某个区域的内存,然后读取该内存。我会在答案中举个简单的例子。 – Dave 2013-03-16 23:43:58

+0

'mpz_get_str'与您所要求的相反:它将大数字转换为您选择的任何(小)基数中的一串数字。 – 2015-05-19 05:25:51

0

GMP附带stdio.h的扩展名,适用于大量数据,请参阅Formatted Input Functions手册。

在标准输入(gmp_scanf),文件(gmp_fscanf)或已经读入内存的字符串(gmp_sscanf)上有通常的口味。