打印

求一个分离(个、十、百、千、万)位的好算法

[复制链接]
楼主: 一棵小草
手机看帖
扫描二维码
随时随地手机跟帖
21
gdqinci| | 2010-6-11 17:27 | 只看该作者 回帖奖励 |倒序浏览
好帖学习了

使用特权

评论回复
22
numLiu| | 2010-6-11 18:08 | 只看该作者
算法真是很奇妙

使用特权

评论回复
23
mohanwei| | 2010-6-11 19:17 | 只看该作者
只要C编译器支持,哪里还有什么一字节加减乘除的限制?编译器自然会调用数学库子程序进行运算的。
大数运算就是一个典型,通过字符串模拟笔算的方法来实现在普通32位机上进行数千位超大数字的运算。
光讨论算法的话用sprintf好了:
char disp_str[10];
uint16 num=12345;
sprintf(disp_str,"%0d",num);

使用特权

评论回复
24
一棵小草|  楼主 | 2010-6-11 19:52 | 只看该作者
只要C编译器支持,哪里还有什么一字节加减乘除的限制?编译器自然会调用数学库子程序进行运算的。
大数运算就是一个典型,通过字符串模拟笔算的方法来实现在普通32位机上进行数千位超大数字的运算。
光讨论算法的话 ...
mohanwei 发表于 2010-6-11 19:17


嘿,你的思想还真奇特。。。
限制还需要理由吗?限制不就是满足条件吗?很难想象,没有条件限制,这个世界会怎么样。。。

当领导说限制你只能用汇编的时候,你能用C吗?你能反对吗?
因为我是出题者,如果没有条件限制,那我问这个还有什么意义?

而且,我考虑的是算法。。。也许我把算法转换成汇编也说不定。如果一开始说汇编,估计没几个人感兴趣,而且算法跟语言没多大关系。。。

使用特权

评论回复
25
mohanwei| | 2010-6-11 20:06 | 只看该作者
C和汇编有什么区别么?
加个#pragma SRC 一类的编译指令不就得到汇编代码了?

使用特权

评论回复
26
一棵小草|  楼主 | 2010-6-11 21:36 | 只看该作者
C和汇编有什么区别么?
加个#pragma SRC 一类的编译指令不就得到汇编代码了?
mohanwei 发表于 2010-6-11 20:06


太能扯了吧,想到什么地方去了?晕。。。

使用特权

评论回复
27
bald| | 2010-6-12 09:09 | 只看该作者
试试这个算法,这里除数都是单字节的:
       X = TEMPA*256+TEMPB           (为了书写方便,编程直接用就行了)

       TEMP5 = (X/40)/250
       X = X MOD 10000
       TEMP4 =   (X/4)/250
       X = X MOD 1000
       TEMP3 =   X/100
       X = X MOD 100
       TEMP2 =   X/10
       TEMP1 = X MOD 10

注意:高字节的余数组合进低位后的进位
用汇编,除法和求余可以同时完成。如果用C,就要受到编译规则的限制了。有兴趣的话可以把编译结果反汇编后看看。

使用特权

评论回复
28
guwu| | 2010-6-12 11:14 | 只看该作者
学习学习

使用特权

评论回复
29
inter_zhou| | 2010-6-12 11:43 | 只看该作者
看看反汇编出来谁能达到12楼的效果

使用特权

评论回复
30
zhf0964| | 2010-6-12 14:25 | 只看该作者
7楼算法精妙,
12楼效率高超。
可谓各有千秋,
都是高手。
呵呵。

使用特权

评论回复
31
dengm| | 2010-6-12 17:23 | 只看该作者
经典算法用 BCD 加法:

;    R7:R6 ==>  R5:R4:R3

     CLR A
     MOV R3, A
     MOV R4, A
     MOV R5, A
  
    MOV R2, #16 ; 16 BIT TO CONVERT
    MOV A, R6
    MOV B, R7  ; B:A
LP1:
       RLC A
       XCH A, B
       RLC A
       XCH A, B
       XCH A, R3
       ADDC A, ACC
       DA A
       XCH A, R3
       XCH A, R4
       ADDC A, ACC
       DA A
       XCH A, R4
       XCH A, R5
       ADDC A, ACC
       DA A
       XCH A, R5
  DJNZ R2, LP1
  RET

使用特权

评论回复
32
dengm| | 2010-6-12 17:33 | 只看该作者
非典算法: 要 除以4 ,  除以250 ........

使用特权

评论回复
33
一棵小草|  楼主 | 2010-6-12 20:02 | 只看该作者
试试这个算法,这里除数都是单字节的:
       X = TEMPA*256+TEMPB           (为了书写方便,编程直接用就行了)

       TEMP5 = (X/40)/250
       X = X MOD 10000
       TEMP4 =   (X/4)/250
       X = ...
bald 发表于 2010-6-12 09:09

这个可能不行,还是没有脱离16位数据的操作。
我认为调用除法是不行的,你看X就是16位了,X/1000也算16位的操作啊。。。
连1000的表示也是16位数据啊,呃,,,难道我说不够清楚?
具体的形式就是像12楼的一样,不出现16位数据。
12楼的思想是减法,算正常的思路,把除法当减法看。
7楼的算法很有参考性,如果能把那16位的比较改成2个8位的比较就很符合要求了。

使用特权

评论回复
34
一棵小草|  楼主 | 2010-6-12 20:07 | 只看该作者
经典算法用 BCD 加法:

;    R7:R6 ==>  R5:R4:R3

     CLR A
     MOV R3, A
     MOV R4, A
     MOV R5, A
  
    MOV R2, #16 ; 16 BIT TO CONVERT
    MOV A, R6
    MOV B, R7  ; B:A
LP1:
       RLC A
     ...
dengm 发表于 2010-6-12 17:23

看着很精简啊,我来算算看行不行

使用特权

评论回复
35
zzyaizll| | 2010-6-12 22:11 | 只看该作者
受益非浅呀

使用特权

评论回复
36
一棵小草|  楼主 | 2010-6-13 13:30 | 只看该作者
按照7楼的算法,自己整理了一下,各位看看:
uchar      bcd_buf[5];       //个,十,百,千,万
uchar      tempH;              //高位
uchar      tempL;              //低位

void        get_16bit_bcd(uchar  *bcd_buf,   uchar  dataH,   uchar  dataL)
{
          uchar    i;
          i=0;
          if(dataH>156 || dataH ==156  && dataL>=64)   //40000=156*256+64
          {  // 思路是:大于或等于40000的都满足条件
                     if(dataL<64) dataH--;        //低位不足,向高位借位
                     dataH -=156;
                     dataL -=64;                       //高位和低位减去的和=40000
                     i += 4;
          }
          if(dataH>78 || dataH ==78  && dataL>=32)   //20000=78*256+32
          {  // 思路是:大于或等于20000的都满足条件
              if(dataL<32) dataH--;        //低位不足,向高位借位
              dataH -=78;
                     dataL -=32;                       //高位和低位减去的和=20000
                     i += 2;
          }
          if(dataH>38 || dataH ==39  && dataL>=16)   //10000=39*256+16
          {  // 思路是:大于或等于10000的都满足条件
              if(dataL<16) dataH--;        //低位不足,向高位借位
              dataH -=39;
                     dataL -=16;                       //高位和低位减去的和=10000
                     i += 1;
          }
           bcd_buf[5] = i;
           i=0;
           //--------下面一样的道理
           -----------以此类推,千位的分7000、4000、2000、1000
           -----------以此类推,百位的分700、400、200、100
           -----------以此类推,十位的分70、40、20、10
           -----------以此类推,个位的分7、4、2、1
}

使用特权

评论回复
37
xlsbz| | 2010-6-13 20:02 | 只看该作者
嘿,你的思想还真奇特。。。
限制还需要理由吗?限制不就是满足条件吗?很难想象,没有条件限制,这个世界会怎么样。。。

当领导说限制你只能用汇编的时候,你能用C吗?你能反对吗?
因为我是出题者,如果没有条 ...
一棵小草 发表于 2010-6-11 19:52


领导说用二进制的话,也不能反驳,只能彻底无语.............;P

使用特权

评论回复
38
一棵小草|  楼主 | 2010-6-14 13:03 | 只看该作者
楼上很有同感啊,跟领导讲话,也许他会听你说完,但最后领导还是说,我要的只是结果,跟我说这个干嘛。。。

使用特权

评论回复
39
一棵小草|  楼主 | 2010-6-14 13:11 | 只看该作者
已经结贴,分数给了7楼,因为已经穿裤,不给就对不起大家了。

还要感谢各位大侠,感谢12楼,自己又长点知识了,呵呵

使用特权

评论回复
40
myworkmail| | 2010-6-29 17:27 | 只看该作者
mark

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则