当没有数据类型可以容纳整数时,将十六进制转换为十进制

问题描述 投票:1回答:5

我正在使用C语言的PIC微处理器,它是16F,所以它不能容纳大于32位的整数(无符号int32是可用的最大数据大小)

[我从阅读器收到一个5字节的ID码。要传输它,我必须逐位编码为BCD。我无法将其冲刺成字符串,因为它大于数据大小,并且无法处理它。我无法划分它,因为没有为它定义任何操作。

我想不出任何可能的解决方案,之前有没有人处理过?

编辑:

我收到一系列5字节的数字:

FF-FF-FF-FF-FF

我需要将其转换为十进制

0123456789012

(13位,长度为256 ^ 5(十进制))通过RS232发送。第二个功能(接收ASCII并发送),我已经可以使用它了,但是我需要使用全数字的字符串表示形式,然后才能对其执行任何操作。

c algorithm bignum pic
5个回答
4
投票

假设您具有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**24的长除法,但在知道除数为1000的情况下进行了预先计算,因此选择了1000,因为它的最小幂数比2**8大10。 >

因此,首先计算最低的三位数,使用(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转换结果进行比较应该很容易。


1
投票

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


1
投票

PIC16F没有硬件乘法或除法单元,因此,除非您乘以2的乘方或除法,否则会对处理器造成负担。这是一个在32位数字上执行BCD且不需要除法或乘法的例程。您可以通过分块进行修改,使其适应5个字节的数字。


0
投票

您总是可以自己手动将它“ sprintf”成字符串。逐字节检查数据,并通过附加各个字符将其转换为数字字符串。


0
投票

我要说的这个问题的核心是要转换为十进制的“长除法”之一。与二年级时所学的长除法完全不同,尽管具有二进制数,但长除法要简单得多。但是它仍然有很多工作。

© www.soinside.com 2019 - 2024. All rights reserved.