好了,所以我用PIC单片机的工作,在C.这是16F,所以它不能保持大于32位的整数(无符号INT32是最大的命令datasize提供)
来自读取器时,收到一个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**16
和y < 2**24
)。
这基本上是在基体长除法2**24
2位值的,但与术语预先计算知道该除数是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的)数字。 这样一来,你可以的sprintf你的ID的最显著字节的字符串“A”,以字符串乘以“4294967296”(256 ^ 4)给你的字符串“B”的sprintf的4个最低显著字节您的ID另一个字符串“C”,并最后加入“B”和“C”。
这不是很性感,尤其是微控制器上,但它的工作原理:)
该PIC16F不具有硬件乘法或除法单元,所以,除非你乘以或由2的幂除,则征税到处理器。 下面是做在一个32位数为BCD并且不需要除法或乘法的例程。 您可以通过在块做适应这5个字节的数字。
空隙BCD32(INT32U努敏){INT8U位= 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
你将不得不实现自己的多字节减法和移位程序。