当没有数据类型可以保存完整数字时,将十进制转换为十六进制

时间:2009-08-13 15:27:36

标签: bit-manipulation bignum pic

几周前,这几乎与我自己的问题完全重复。

Convert Hex to Decimal when no datatype can hold the full number

这一次,情况正好相反。我有数字(在一个方便的空终止字符串中),我需要产生这个数字的字节。但是,我在微控制器的32位架构中工作,因此我没有使用atoi的可能性,因为数字大于32位。

有没有人知道如何反转第一个链接中提供的算法,以便取回原始结果?我的模运算技能让我失望。

快速示例: 155.207.231.135 0x [24] [23] [12] [66] [9F] (括号将字节分开)

3 个答案:

答案 0 :(得分:1)

您可以执行与BigInt部门类似的操作。

a = atoi of lower 7 decimal digits
b = atoi of remaining upper decimal digits


for (int i = 0; i < 5; i++)
{
    a += 10000000 * (b % 256);
    b /= 256;
    Result[i] = a % 256;
    a /= 256;
}

答案 1 :(得分:0)

你需要这个汇编程序。伪代码:

int low = 0 // lower 32 bit
int high = 0 // higher 32 bit

for (int i=0; i<string.length(); i++) {
    int digit = string.get(i) - '0';
    int a = low;
    int b = high;
    a <<= 1; b += overflow;             // *2
    a <<= 1; b += overflow;             // *4
    a += low; b += overflow; b += high; // *5
    a <<= 1; b += overflow;             // *10
    a += digit; b += overflow;          // +digit
    low = a; high = b;
}

基本上,你使用两个32位整数创建一个64位寄存器。对于每个循环,您:

    value *= 10 + digit;

之后,您只需跳过结果值开头的0字节即可获得所需的字节数。

答案 2 :(得分:0)

只需从左到右解析字符串,将前一个结果乘以10并添加数字。

这是C#中的一些代码来展示这个概念。前两个在数组上进行数学运算的方法:

static void Mul(byte[] data, int num) {
   int n = 0;
   for (int i = data.Length - 1; i >= 0; i--) {
      n += (int)data[i] * num;
      data[i] = (byte)n;
      n >>= 8;
   }
}

static void Add(byte[] data, int num) {
   for (int i = data.Length - 1; num > 0; i-- ) {
      num += (int)data[i];
      data[i] = (byte)num;
      num >>= 8;
   }
}

然后你就做了:

string s = "155207231135";
byte[] result = new byte[16];
foreach (char c in s) {
   Mul(result, 10);
   Add(result, c - '0');
}

结果在result数组中,左边用零字节填充。

不应该很难翻译成C ......:)