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

好的,所以我在C中使用PIC微处理器。它是一个16F,因此它不能保存大于32位的整数(unsigned int32是可用的最大数据量)

从阅读器,我收到一个5字节的ID代码。 为了传输它,我必须逐位编码为BCD。 我无法将其打印到字符串,因为它比数据大小大,并且无法处理它。 我无法分割它,因为没有为它定义操作。

我无法找出任何解决方案,有没有人以前处理过这个问题?

编辑:

我收到一系列5个字节的数字:“FF-FF-FF-FF-FF”。 我需要将其转换为十进制“0123456789012”(13位数,长度为256 ^ 5十进制),以通过RS232发送。 第二个函数(使用ASCII,并发送它)我已经有它工作,但我需要完整数字的字符串表示,然后我可以用它做任何事情。

假设您有32位算术:2 ** 24 = 16777216,所以将x视为最重要的2字节,将y视为最不重要的3:

(16777216 * x + y) / 1000 = (16777000 * x + 216 * x + y) / 1000 = 16777 * x + (216 * x + y) / 1000 

第一项可以在没有溢出的情况下以32位计算(因为x < 2**16 )。 第二项也可以在没有溢出的情况下计算(因为x < 2**16y < 2**24 )。

这基本上是2位数值的基数2**24中的长除法,但是在知道除数为1000的情况下预先计算的项。选择了1000,因为它是10的最小幂大于2**8

因此,首先计算最低的三位数,使用(2**32) % 1000 == 296的事实。 所以这次我们将x作为最高字节,y作为低4字节

 ((2**32) * x + y) % 1000 = ((2**32) * x) % 1000 + y % 1000 (modulo 1000) = (296 * x) % 1000 + y % 1000 (modulo 1000) ((2**32) * x + y) % 1000 = ((296 * x) % 1000 + y % 1000) % 1000 

然后使用上面的公式将原始数字除以1000。 然后你可以安全地进入32位领域,并可以使用正常循环生成剩余的数字。

顺便说一句,如果我是你,我会检查结果:我没有测试过这个,我可能在某个地方犯了错误。 应该很容易与使用PC上64位整数的常用方法完成的bcd转换结果进行比较。

我要做的是对编码为字符串的数字(一种BigNum)实现加法和乘法。 这样,您可以将ID的最重要字节sprintf为字符串“A”,将其与字符串“4294967296”(256 ^ 4)相乘,为您提供字符串“B”,sprintf为您ID中的4个最低字节另一个字符串“C”,最后添加“B”和“C”。

它不是很性感,特别是在微控制器上,但它的工作原理:)

PIC16F没有硬件乘法或除法单元,因此除非您乘以或除以2的幂,否则它对处理器造成负担。 这是一个在32位数字上执行BCD且不需要除法或乘法的例程。 您可以通过以块为单位将其调整为5字节数。

void BCD32(int32u numIn){int8u digit = 0;

 while (numIn >= 1000000000) { numIn -= 1000000000; digit++; } debug[0] = digit + 48; digit = 0; while (numIn >= 100000000) { numIn -= 100000000; digit++; } debug[1] = digit + 48; digit = 0; while (numIn >= 10000000) { numIn -= 10000000; digit++; } debug[2] = digit + 48; digit = 0; while (numIn >= 1000000) { numIn -= 1000000; digit++; } debug[3] = digit + 48; digit = 0; while (numIn >= 100000) { numIn -= 100000; digit++; } debug[4] = digit + 48; digit = 0; while (numIn >= 10000) { numIn -= 10000; digit++; } debug[5] = digit + 48; digit = 0; while (numIn >= 1000) { numIn -= 1000; digit++; } debug[6] = digit + 48; digit = 0; while (numIn >= 100) { numIn -= 100; digit++; } debug[7] = digit + 48; digit = 0; while (numIn >= 10) { numIn -= 10; digit++; } debug[8] = digit + 48; digit = 0; while (numIn >= 1) { numIn -= 1; digit++; } debug[9] = digit + 48; debug[10] = CARRIAGE_RETURN; debug[11] = NEW_LINE_FEED; SendUart(12); 

}

您可以自己手动将其“sprintf”为字符串。 遍历字节后的数据字节,并通过附加单个字符将其转换为数字字符串。

我要说的这个问题的核心是转换为十进制的“长除法”之一。 与你在小学阶段学到的长分并不完全不同,尽管使用二进制数,长分割更简单。 但它仍然需要做很多工作。

尝试:
http://mathforum.org/library/drmath/view/55951.html

您必须实现自己的多字节减法和移位例程。