请问下,4节字节的长整型数转换为BCD码,怎么样做最快呢。。

2020-01-16 18:31发布

假设一个,long int k = 1234567890;转换为,unsigned char k1[10];

这个应该怎么算比较好呢。比较常见的是,
for(i =0 ;i<10;i++)
{
k1 = k%10;
k/=10;
}

应该有更简单的吧。。
谢谢!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
18条回答
eduhf_123
2020-01-17 03:45
帖一个我做的库:

NAME    LONG2BCD

?PR?_long2bcd?LONG2BCD                SEGMENT CODE INBLOCK
        PUBLIC  _long2bcd
; void long2bcd(unsigned long l, unsigned char * p)

        RSEG  ?PR?_long2bcd?LONG2BCD
_long2bcd:
        MOV     R3,     #0x05
        CLR     A
?C0001: MOV     @R1,    A
        INC     R1
        DJNZ    R3,     ?C0001

        MOV     A,      #0x08
        MOV     R2,     A
?C0002: XCH     A,      R4
        RLC     A
        XCH     A,      R4
        MOV     R3,     #0x02
?C0003: DEC     R1
        XCH     A,      @R1
        RLC     A
        MOV     0xD5,   C               ;PSW.5,F0
        ADD     A,      #0x33
        JB      0xE3,   ?C0004          ;ACC.3
        ADD     A,      #(-3)
?C0004: JB      0xE7,   ?C0005          ;ACC.7
        ADD     A,      #(-48)
?C0005: MOV     C,      0xD5            ;PSW.5,F0
        XCH     A,      @R1
        DJNZ    R3,     ?C0003
        INC     R1
        INC     R1
        DJNZ    R2,     ?C0002

        MOV     R2,     A
?C0006: XCH     A,      R5
        RLC     A
        XCH     A,      R5
        MOV     R3,     #0x03
?C0007: DEC     R1
        XCH     A,      @R1
        RLC     A
        MOV     0xD5,   C
        ADD     A,      #0x33
        JB      0xE3,   ?C0008
        ADD     A,      #(-3)
?C0008: JB      0xE7,   ?C0009
        ADD     A,      #(-48)
?C0009: MOV     C,      0xD5
        XCH     A,      @R1
        DJNZ    R3,     ?C0007
        INC     R1
        INC     R1
        INC     R1
        DJNZ    R2,     ?C0006

        MOV     R2,     A
?C000A: XCH     A,      R6
        RLC     A
        XCH     A,      R6
        MOV     R3,     #0x04
?C000B: DEC     R1
        XCH     A,      @R1
        RLC     A
        MOV     0xD5,   C
        ADD     A,      #0x33
        JB      0xE3,   ?C000C
        ADD     A,      #(-3)
?C000C: JB      0xE7,   ?C000D
        ADD     A,      #(-48)
?C000D: MOV     C,      0xD5
        XCH     A,      @R1
        DJNZ    R3,     ?C000B
        INC     R1
        INC     R1
        INC     R1
        INC     R1
        DJNZ    R2,     ?C000A

        MOV     R2,     A
?C000E: XCH     A,      R7
        RLC     A
        XCH     A,      R7
        MOV     R3,     #0x05
?C000F: DEC     R1
        XCH     A,      @R1
        RLC     A
        MOV     0xD5,   C
        CJNE    R2,     #1,     ?C0010
        SJMP    ?C0012
?C0010: ADD     A,      #0x33
        JB      0xE3,   ?C0011
        ADD     A,      #(-3)
?C0011: JB      0xE7,   ?C0012
        ADD     A,      #(-48)
?C0012: MOV     C,      0xD5
        XCH     A,      @R1
        DJNZ    R3,     ?C000F
        INC     R1
        INC     R1
        INC     R1
        INC     R1
        INC     R1
        DJNZ    R2,     ?C000E

        RET         

        END


所用算法的流程图 (原文件名:hex2bcd.JPG)

C语言的调用接口已在程序中以注释的方式给出,需要注意的是,程序需要传递一个通用指针进去,但函数内部的代码实际上只能处理该指针为“unsigned char data *”的形式,也就是说,存储BCD码结果的数组只能在DATA区。结果为压缩BCD码,存于传进来的指针所指的5个元素的数组。

附上库文件工程包、测试工程包:
生成.LIB库文件的工程包ourdev_549026.rar(文件大小:5K) (原文件名:long2bcd.rar)
功能测试及、与除法及取模运算方式对比的工程包ourdev_549027.rar(文件大小:7K) (原文件名:temp.rar)

在标准51架构上,该函数使用2174周期、而作为对比的除法/取模方式要用4700周期。
本想使用div/ldiv库来改善除法/取模方式的效率,结果查阅Keil的帮助才发现,Keil C不支持这两个ANSI-C的库,看样子有必要自己写一个。

一周热门 更多>