VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: VBProFan

VBProFan原创作品开源展示之五:高精度计算器

[复制链接]
发表于 2007-9-22 20:39:29 | 显示全部楼层
原帖由 YaDa 于 2007-9-22 11:24 发表
阅读权限80,现在看起来并不高,一下子就超越了。前面有几个说:“阅读权限不够”的,现在已经有150了。

上次阅读权限不够,这次就可以看看庐山真面目了。



回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-22 22:02:30 | 显示全部楼层
忙了一天,终于翻译了加、减、乘三个函数并测试通过,就差个除法了,先借论坛贵宝地备份一下,谢谢了


  1. void Byte2String(unsigned char Byte, char sResult[])
  2. {
  3.         unsigned char i;
  4.         unsigned char temp;
  5.         unsigned long Digits;
  6.        
  7.         i = 0;
  8.         while(Byte > 0)
  9.         {
  10.                 sResult[i] = (Byte % 10) + '0';
  11.                 Byte = (unsigned char)(Byte / 10);
  12.                 i++;
  13.         }
  14.        
  15.         Digits = i;
  16.         for(i=0; i<=(unsigned char)(Digits / 2) - 1; i++)
  17.         {  
  18.                 temp=sResult[i];
  19.                 sResult[i] = sResult[Digits - 1];
  20.                 sResult[Digits - 1] = temp;
  21.         }
  22.        
  23.         sResult[Digits] = '\0';
  24. }

  25. unsigned char Greater(char s1[], char s2[])
  26. {
  27.         if ((strlen(s1) > strlen(s2)) || (strcmp(s1,s2) > 0))
  28.                 return 1;
  29.         else
  30.                 return 0;
  31. }

  32. void Normalize(char s1[], char s2[], char sa[],char sb[])
  33. {
  34.         char sTemp[10];
  35.         unsigned char i;

  36.         if (strlen(s1) < strlen(s2))
  37.         {
  38.                 strcpy(sa,s2);
  39.                 strcpy(sb,s1);
  40.         }
  41.         else
  42.         {
  43.                 strcpy(sa,s1);
  44.                 strcpy(sb,s2);
  45.         }
  46.         sTemp[0]='\0';
  47.        
  48.         for (i=1; i<=strlen(sa)-strlen(sb); i++)
  49.         {
  50.                 strcat(sTemp,"0");
  51.         }
  52.         strcat(sTemp,sb);
  53.         strcpy(sb,sTemp);
  54. }

  55. void HSum(char s1[], char s2[], char sResult[])
  56. {
  57.         signed char i;
  58.         unsigned char DigitSum;
  59.         unsigned char Carry;
  60.         char sTemp[10];
  61.         char sa[10];
  62.         char sb[10];
  63.        
  64.         Normalize(s1,s2,sa,sb);
  65.         Carry=0;
  66.         for (i=strlen(sa)-1; i>=0; i--)
  67.         {
  68.                 DigitSum = (sa[i]-'0') + (sb[i]-'0') + Carry;
  69.                 Carry = (DigitSum >= 10 ? 1 : 0);
  70.                 sResult[i] = (DigitSum % 10) + '0';
  71.         }
  72.         sResult[strlen(sa)]='\0';

  73.         if (Carry==1)
  74.         {
  75.                 strcpy(sTemp,"1");
  76.                 strcat(sTemp,sResult);
  77.                 strcpy(sResult,sTemp);
  78.         }
  79. }

  80. void HSub(char s1[], char s2[], char sResult[])
  81. {
  82.         signed char i;
  83.         signed char DigitDiff;
  84.         unsigned char Borrow;
  85.         char sa[10];
  86.         char sb[10];
  87.        
  88.         Normalize(s1,s2,sa,sb);
  89.         Borrow=0;
  90.         for (i=strlen(sa)-1; i>=0; i--)
  91.         {
  92.                 DigitDiff = (sa[i]-'0') - (sb[i]-'0') - Borrow;
  93.                 Borrow = (DigitDiff < 0 ? 1 : 0);
  94.                 sResult[i] = DigitDiff + (DigitDiff < 0 ? 10 : 0) + '0';
  95.         }
  96.         sResult[strlen(sa)]='\0';
  97. }

  98. void HMulS(char s[], unsigned char n, char sResult[])
  99. {
  100.         signed char i;
  101.         unsigned char DigitProduct;
  102.         unsigned char Carry;
  103.         char sTemp[10];

  104.         Carry = 0;
  105.         for (i=strlen(s)-1; i>=0; i--)
  106.         {
  107.                 DigitProduct = (s[i] - '0') * n + Carry;
  108.                 Carry = (unsigned char)(DigitProduct / 10);
  109.                 sResult[i] = (DigitProduct % 10) + '0';
  110.         }
  111.         sResult[strlen(s)]='\0';

  112.         if (Carry > 0)
  113.         {
  114.                 Byte2String(Carry, sTemp);
  115.                 strcat(sTemp,sResult);
  116.                 strcpy(sResult,sTemp);
  117.         }
  118. }

  119. void HMul(char s1[], char s2[], char sResult[])
  120. {
  121.         signed char i;
  122.         signed char j;
  123.         char sa[10];
  124.         char sb[10];
  125.         char sTemp[10];

  126.         Normalize(s1,s2,sa,sb);
  127.         strcpy(sResult,"0");
  128.         for (i=strlen(sb)-1; i>=0; i--)
  129.         {
  130.                 HMulS(sa,sb[i]-'0',sTemp);
  131.                 for (j=1; j <= (strlen(sb) - 1) - i; j++)
  132.                         strcat(sTemp,"0");
  133.                 HSum(sResult,sTemp,sResult);
  134.         }
  135. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-9-22 22:43:54 | 显示全部楼层
如果仅仅是大硬盘的计算
代码不会很多的吧?
加减法就不说了
乘法是64次二进制加法就可以了吧?这个方法比较笨吧,但是看起来很简单
除法不知道
地址计算应该不会用到除法吧
回复 支持 反对

使用道具 举报

发表于 2007-9-22 22:57:33 | 显示全部楼层
34楼的书写非常规范,赞一声。

这C语言,说起来是自由灵活,实际上反而不好。不加花括号,错误陷阱多;加了花括号,比VB还多占一行。还不如“End If”、“Next”来得可爱。行尾还必须加分号,真难受。

我最喜欢的还是VB的语法及书写风格。
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2007-9-23 13:36:27 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-23 14:41:22 | 显示全部楼层

全部做完了,并通过了一个测试数据,再备份一次


  1. /*
  2. Print DateDiff("s", "1980-1-1 08:00:00", "2007-3-17 16:07:45")
  3. 858586065

  4.   从1980-1-1 08:00:00到2007-3-17 16:07:45的秒数为858586065秒。
  5.   
  6.         因此,9f ec 92 ee 05 这五个字节包含的信息是2007-3-17 16:07:45
  7. */

  8. #include <stdio.h>
  9. #include <string.h>

  10. void Byte2String(unsigned char Byte, char sResult[])
  11. {
  12.         unsigned char i;
  13.         unsigned char temp;
  14.         unsigned long Digits;
  15.        
  16.         i = 0;
  17.         while(Byte > 0)
  18.         {
  19.                 sResult[i] = (Byte % 10) + '0';
  20.                 Byte = (unsigned char)(Byte / 10);
  21.                 i++;
  22.         }
  23.        
  24.         Digits = i;
  25.         for(i=0; i<=(unsigned char)(Digits / 2) - 1; i++)
  26.         {  
  27.                 temp=sResult[i];
  28.                 sResult[i] = sResult[Digits - 1];
  29.                 sResult[Digits - 1] = temp;
  30.         }
  31.        
  32.         sResult[Digits] = '\0';
  33. }

  34. void String2Byte(char s[],unsigned char *n)
  35. {
  36.         if (strlen(s)==2)
  37.                 *n = (s[0]-'0') * 10 + (s[1]-'0');
  38.         else
  39.                 *n = s[0] - '0';
  40. }

  41. void LTrim0(char s[])
  42. {
  43.         unsigned char i;

  44.         if (s[0]=='0' && strlen(s) > 1)
  45.         {
  46.                 for  (i=0; i<=strlen(s)-2; i++)
  47.                 {
  48.                         s[i]=s[i+1];
  49.                 }
  50.                 s[strlen(s)-1]='\0';
  51.         }
  52. }
  53. unsigned char Greater(char s1[], char s2[])
  54. {

  55.         LTrim0(s2);

  56.         if ((strlen(s1) > strlen(s2)) || ((strcmp(s1,s2) > 0) && (strlen(s1) == strlen(s2))))
  57.                 return 1;
  58.         else
  59.                 return 0;
  60. }

  61. void Normalize(char s1[], char s2[], char sa[],char sb[])
  62. {
  63.         char sTemp[13];
  64.         unsigned char i;

  65.         if (strlen(s1) < strlen(s2))
  66.         {
  67.                 strcpy(sa,s2);
  68.                 strcpy(sb,s1);
  69.         }
  70.         else
  71.         {
  72.                 strcpy(sa,s1);
  73.                 strcpy(sb,s2);
  74.         }
  75.         sTemp[0]='\0';
  76.        
  77.         for (i=1; i<=strlen(sa)-strlen(sb); i++)
  78.         {
  79.                 strcat(sTemp,"0");
  80.         }
  81.         strcat(sTemp,sb);
  82.         strcpy(sb,sTemp);
  83. }

  84. void HSum(char s1[], char s2[], char sResult[])
  85. {
  86.         signed char i;
  87.         unsigned char DigitSum;
  88.         unsigned char Carry;
  89.         char sTemp[13];
  90.         char sa[13];
  91.         char sb[13];
  92.        
  93.         Normalize(s1,s2,sa,sb);
  94.         Carry=0;
  95.         for (i=strlen(sa)-1; i>=0; i--)
  96.         {
  97.                 DigitSum = (sa[i]-'0') + (sb[i]-'0') + Carry;
  98.                 Carry = (DigitSum >= 10 ? 1 : 0);
  99.                 sResult[i] = (DigitSum % 10) + '0';
  100.         }
  101.         sResult[strlen(sa)]='\0';

  102.         if (Carry==1)
  103.         {
  104.                 strcpy(sTemp,"1");
  105.                 strcat(sTemp,sResult);
  106.                 strcpy(sResult,sTemp);
  107.         }
  108. }

  109. void HSub(char s1[], char s2[], char sResult[])
  110. {
  111.         signed char i;
  112.         signed char DigitDiff;
  113.         unsigned char Borrow;
  114.         char sa[13];
  115.         char sb[13];
  116.        
  117.         Normalize(s1,s2,sa,sb);
  118.         Borrow=0;
  119.         for (i=strlen(sa)-1; i>=0; i--)
  120.         {
  121.                 DigitDiff = (sa[i]-'0') - (sb[i]-'0') - Borrow;
  122.                 Borrow = (DigitDiff < 0 ? 1 : 0);
  123.                 sResult[i] = DigitDiff + (DigitDiff < 0 ? 10 : 0) + '0';
  124.         }
  125.         sResult[strlen(sa)]='\0';
  126. }

  127. void HMulS(char s[], unsigned char n, char sResult[])
  128. {
  129.         signed char i;
  130.         unsigned char DigitProduct;
  131.         unsigned char Carry;
  132.         char sTemp[13];

  133.         Carry = 0;
  134.         for (i=strlen(s)-1; i>=0; i--)
  135.         {
  136.                 DigitProduct = (s[i] - '0') * n + Carry;
  137.                 Carry = (unsigned char)(DigitProduct / 10);
  138.                 sResult[i] = (DigitProduct % 10) + '0';
  139.         }
  140.         sResult[strlen(s)]='\0';

  141.         if (Carry > 0)
  142.         {
  143.                 Byte2String(Carry, sTemp);
  144.                 strcat(sTemp,sResult);
  145.                 strcpy(sResult,sTemp);
  146.         }
  147. }

  148. void HMul(char s1[], char s2[], char sResult[])
  149. {
  150.         signed char i;
  151.         unsigned char j;
  152.         char sTemp[13];

  153.         strcpy(sResult,"0");
  154.         for (i=strlen(s2)-1; i>=0; i--)
  155.         {
  156.                 HMulS(s1,s2[i]-'0',sTemp);
  157.                 for (j=1; j <= (strlen(s2) - 1) - i; j++)
  158.                         strcat(sTemp,"0");
  159.                 HSum(sResult,sTemp,sResult);
  160.         }
  161. }

  162. void HDiv(char s1[], char s2[], char sResult[], char sRemainder[])
  163. {
  164.         unsigned char i;
  165.         unsigned char j;
  166.         char sa[13];
  167.         char sProduct[13];

  168.         strcpy(sa,s1);
  169.         sa[strlen(s2)]='\0';

  170.         sResult[strlen(s1)-strlen(s2)+1]='\0';
  171.         for (i=strlen(s2); i<=strlen(s1); i++)
  172.         {
  173.                 j = 10;
  174.                 do
  175.                 {
  176.                         j--;
  177.                         HMulS(s2,j,sProduct);
  178.                 }while(Greater(sProduct,sa) && j!=0);

  179.                 sResult[i-strlen(s2)] = j+'0';
  180.                 HSub(sa,sProduct,sa);
  181.                 sa[strlen(sa)+1]='\0';
  182.                 sa[strlen(sa)]=s1[i];
  183.         }
  184.         LTrim0(sa);
  185.         strcpy(sRemainder,sa);
  186. }

  187. void GetTime(unsigned char a4,
  188.           unsigned char a3,
  189.           unsigned char a2,
  190.           unsigned char a1,
  191.           unsigned char *Hr,
  192.           unsigned char *Min,
  193.           unsigned char *Sec)
  194. {
  195.         char s4[13];
  196.         char s3[13];
  197.         char s2[13];
  198.         char s1[13];
  199.         char sd[13];
  200.         char sc[13];
  201.         char sb[13];
  202.         char sa[13];
  203.         char  s[13];

  204. // (858586065 / 3600 + 8) % 24 = 16
  205. // (858586065 / 60) % 60 = 7
  206. // 858586065 % 60 = 45

  207.         //把4个字节参数转为字符串
  208.         Byte2String(a4,s4);
  209.         Byte2String(a3,s3);
  210.         Byte2String(a2,s2);
  211.         Byte2String(a1,s1);

  212.         //把4个字节参数和00字节组合成5字节数
  213.         HMul("4294967296",s4,sd);// 256^4 * a4
  214.         HMul("16777216",s3,sc);  // 256^3 * a3
  215.         HMul("65536",s2,sb);     // 256^2 * a2
  216.         HMul("256",s1,sa);       // 256^1 * a1
  217.        
  218.         strcpy(s,"0");
  219.         HSum(s,sa,s);
  220.         HSum(s,sb,s);
  221.         HSum(s,sc,s);
  222.         HSum(s,sd,s);
  223.        
  224.         HDiv(s,"800",sa,sd);//得到绝对秒数sa
  225.         LTrim0(sa);

  226.         HDiv(sa,"3600",sc,sd);
  227.         HSum(sc,"8",sb);
  228.         HDiv(sb,"24",sc,sd); // sd就是BJ时
  229.         String2Byte(sd,Hr);

  230.         HDiv(sa,"60",sb,sd); // sd就是BJ秒
  231.         String2Byte(sd,Sec);

  232.         HDiv(sb,"60",sc,sd); // sd就是BJ分
  233.         String2Byte(sd,Min);
  234. }

  235. void main()
  236. {
  237.         unsigned char a4=0x9f; //159
  238.         unsigned char a3=0xec; //236
  239.         unsigned char a2=0x92; //146
  240.         unsigned char a1=0xee; //238
  241.         unsigned char a0=0x05; //  5
  242.         unsigned char Hr,Min,Sec;
  243.                
  244.         GetTime(a4,a3,a2,a1,&Hr,&Min,&Sec);
  245.         printf("%d,%d,%d\n",Hr,Min,Sec);
  246. }
复制代码


PS:这段C代码并非顶楼VB代码的等价翻译,而是为了某个具体的应用做了许多简化的假设,还有为了节省单片机的内存,某些地方就不考虑可读性和可维护性,把变量复用了。但是还可以用更省内存的方式来编。

[ 本帖最后由 VBProFan 于 2007-9-23 14:59 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-23 14:45:50 | 显示全部楼层
原帖由 YaDa 于 2007-9-22 22:57 发表
34楼的书写非常规范,赞一声。


这是我这几天才重写的,当然规范了。顶楼的那个是N年前写的,那时为了偷懒,变量名只取几个字母,现在看上去都觉得不顺眼,不住地问:这是我写的吗?怎么那么烂啊?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-23 14:51:35 | 显示全部楼层
原帖由 失去与等待 于 2007-9-22 22:43 发表
如果仅仅是大硬盘的计算
代码不会很多的吧?
加减法就不说了
乘法是64次二进制加法就可以了吧?这个方法比较笨吧,但是看起来很简单
除法不知道
地址计算应该不会用到除法吧


回superzmy大侠:
写这个程序是为了计算Pi,然后后来写大硬盘计算时就不用重新写代码了,而利用这个程序中的函数。
回复 支持 反对

使用道具 举报

发表于 2007-9-23 15:01:27 | 显示全部楼层
原帖由 VBProFan 于 2007-9-23 14:51 发表
回superzmy大侠:



你那么肯定?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-23 15:27:00 | 显示全部楼层
刚才去水房看了一下,lose & wait 否定了自己,但是他们的风格真的很像啊,我不知道该相信他说的话还是相信自己的感觉。。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2019-10-14 12:31

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表