这与几周前我自己的问题几乎完全相同。
这一次,情况正好相反。我有数字(在一个方便的空终止字符串中),我需要构成这个数字的字节。但是,我正在为微控制器使用 32 位架构,因此我无法使用 atoi,因为该数字大于 32 位。
有没有人知道如何反转第一个链接中提供的算法以取回原始结果?我的模数算术技能让我失望了。
快速示例:155.207.231.135到0x[24][23][12][66][9F](括号分隔字节)
这与几周前我自己的问题几乎完全相同。
这一次,情况正好相反。我有数字(在一个方便的空终止字符串中),我需要构成这个数字的字节。但是,我正在为微控制器使用 32 位架构,因此我无法使用 atoi,因为该数字大于 32 位。
有没有人知道如何反转第一个链接中提供的算法以取回原始结果?我的模数算术技能让我失望了。
快速示例:155.207.231.135到0x[24][23][12][66][9F](括号分隔字节)
您可以执行类似于 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;
}
您需要为此使用汇编程序。伪代码:
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 字节即可获得您要查找的字节。
只需从左到右解析字符串,将前一个结果乘以十并添加数字。
这是 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 语言应该不难... :)