免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 10438 | 回复: 20

一个银行存款本息自动计算程序,或许有人会有用 [复制链接]

论坛徽章:
0
发表于 2011-12-15 11:52 |显示全部楼层
网上查了,没有太好用的。银行给出的在线计算都要输入利息,这个要求属于扯淡。

这个自动计算要输入的是本金,存入日期,存入期限(活期,死期0.5年,1,2,3,5年)
和取款日期。

如果不输入取款日期,假设今天取款。
如果输入D为取款日期,则假设以后到期了取款。

我实验了,基本正确。

只能计算活期,或整存整取,不能计算其它灵活的存取类型。
  1. //bank interest auto calculation.
  2. //Coding by SEEKER. 2011.12.15

  3. #include <stdio.h>
  4. #include <float.h>
  5. #define _XOPEN_SOURCE /* glibc2 needs this */
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <string.h>


  9. char *intrests = "\
  10. 06/10/1999        0.99        2.16        2.25        2.43        2.7        2.88  \n\
  11. 02/21/2002        0.72        1.89        1.98        2.25        2.52        2.79  \n\
  12. 10/29/2004        0.72        2.07        2.25        2.7        3.24        3.6   \n\
  13. 08/19/2006        0.72        2.25        2.52        3.06        3.69        4.14  \n\
  14. 03/18/2007        0.72        2.43        2.79        3.33        3.96        4.41  \n\
  15. 05/19/2007        0.72        2.61        3.06        3.69        4.41        4.95  \n\
  16. 07/21/2007        0.81        2.88        3.33        3.96        4.68        5.22 \n\
  17. 08/22/2007        0.81        3.15        3.6        4.23        4.95        5.49 \n\
  18. 09/15/2007        0.81        3.42        3.87        4.5        5.22        5.76 \n\
  19. 12/21/2007        0.72        3.78        4.14        4.68        5.4        5.85 \n\
  20. 10/09/2008        0.72        3.51        3.87        4.41        5.13        5.58 \n\
  21. 10/30/2008        0.72        3.24        3.6        4.14        4.77        5.13 \n\
  22. 11/27/2008        0.36        2.25        2.52        3.06        3.6        3.87 \n\
  23. 12/23/2008        0.36        1.98        2.25        2.79        3.33        3.6 \n\
  24. 10/20/2010        0.36        2.2        2.5        3.25        3.85        4.2 \n\
  25. 12/26/2010        0.36        2.5        2.75        3.55        4.15        4.55 \n\
  26. 02/09/2011        0.4        2.8        3        3.9        4.5        5 \n\
  27. 04/06/2011        0.5        3.05        3.25        4.15        4.75        5.25 \n\
  28. 07/07/2011        0.5        3.3        3.5        4.4        5        5.5 \n\
  29. ";

  30. struct intr_list {
  31.         time_t  from, to;
  32.         float        intr_temp;
  33.         float        intr_half;
  34.         float        intr_y1;
  35.         float        intr_y2;
  36.         float        intr_y3;
  37.         float        intr_y5;

  38. } intr_list[20];
  39. int intr_max;

  40. char *yasctime(struct tm *t)
  41. {
  42. static char buf[32];
  43.     sprintf(buf, "%d-%d-%d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
  44.     return buf;
  45.     /*
  46.     char *tp;
  47.     char *cp = asctime(t);
  48.     tp = strrchr(cp, '\n');
  49.     if(tp) *tp = 0;
  50.     return cp;
  51.     */
  52. }

  53. time_t addtime(time_t t, float length)
  54. {
  55. struct tm tm;
  56.    
  57.     tm = *localtime(&t);
  58.     if(length >= 1.0) {
  59.             tm.tm_year += length;
  60.     } else if(length == 0.5) {
  61.         tm.tm_year += tm.tm_mon/6; //0-5 keep old, 6-11 inc
  62.         tm.tm_mon += 6;
  63.         tm.tm_mon %= 12;
  64.     }
  65.     return mktime(&tm);
  66. }

  67. float  INTR_TAX = 0; //0.05 previously
  68. float  deposit_rmb;
  69. time_t deposit_time;
  70. float  deposit_period;
  71. time_t withdraw_time; //if empty, today

  72. float get_interest(time_t tm, float p)
  73. {
  74. int i;

  75.     if(tm < intr_list[0].from) {
  76.         printf("error 0. no data\n");
  77.         return 0;
  78.     }
  79.     //if(tm > intr_list[intr_max-1].from) {
  80.     //        printf("error 1. no data\n");
  81.     //        return 0;
  82.     //}
  83.     if(tm > intr_list[intr_max-1].from) {
  84.         i = intr_max - 1;
  85.         goto get_it;

  86.     }
  87.    
  88.     for(i = 0; i < intr_max; i++) {
  89.                if(tm >= intr_list[i].from && tm < intr_list[i+1].from) {
  90.         get_it:
  91.             if(p == 0.0) return intr_list[i].intr_temp;
  92.             if(p == 0.5) return intr_list[i].intr_half;
  93.             if(p == 1.0) return intr_list[i].intr_y1;
  94.             if(p == 2.0) return intr_list[i].intr_y2;
  95.             if(p == 3.0) return intr_list[i].intr_y3;
  96.             if(p == 5.0) return intr_list[i].intr_y5;
  97.        
  98.             printf("error 2.\n");
  99.         }
  100.     }
  101.     printf("error 3.\n");

  102. }

  103. calc_it(time_t dt, float length, time_t wt)
  104. {
  105. int last = 0;
  106. float intr, intr_rmb;
  107. time_t due_time;
  108. struct tm tm, *tp;
  109. float total;

  110.     total = deposit_rmb;
  111. loop:
  112.     if(last) return;
  113.     //printf(" withdraw %s\n", yasctime(localtime(&wt)));

  114.     //      if((unsigned long)dt >= (unsigned long)withdraw_time) {
  115.     //if(difftime(wt, dt) < 0.0)        return;
  116.     if(difftime(wt, dt) < 3600*24*4) return;
  117.    
  118.     printf("> start %s  %.1f year period:\n", yasctime(localtime(&dt)), length);
  119.     if(length >= 0.5) { //huo qi interest assumed
  120.         if(difftime(wt, dt) < 3600*24*365*length) {
  121.            length = -difftime(wt, dt)/3600/24/365;
  122.              last = 1;
  123.            printf("last flexible peroid. length year = %.2f\n", -length);
  124.         }
  125.     }
  126.     intr = get_interest(dt, length > 0.0? length: 0.0);
  127.     printf("base rmb: %.2f\n", total);
  128.     printf("yearly interest %.2f\n", intr);

  129.     //tm hold this segment's deadline
  130.     tm = *localtime(&dt);
  131.     if(length >= 1.0) {
  132.             tm.tm_year += length;
  133.     } else if(length == 0.5) {
  134.         /*
  135.         if(tm.tm_mon <= 5)  //1-6 yue
  136.            tm.tm_mon += 6;
  137.         else {
  138.            tm.tm_mon += 6;
  139.            tm.tm_mon %= 12;
  140.            tm.tm_year++;
  141.         }
  142.         */
  143.         tm.tm_year += tm.tm_mon/6; //0-5 keep old, 6-11 inc
  144.         tm.tm_mon += 6;
  145.         tm.tm_mon %= 12;
  146.     } else if(length < 0.0) { //last huo qi
  147.         length = -length;
  148.         tm = *localtime(&wt);
  149.     } else if(length == 0.0) { //is huo qi
  150.         length = difftime(wt, dt)/3600/24/365;
  151.         tm = *localtime(&wt);
  152.           last = 1;
  153.         printf("flexible peroid. length year = %.2f\n", length);
  154.     } else
  155.         printf("error of length.\n");
  156.    
  157.     due_time = mktime(&tm);         
  158.     tp = localtime(&due_time);
  159.     printf("due time %s\n", yasctime(tp));

  160.     intr_rmb = (total*intr/100.0)*length;
  161.     printf("initial interest rmb %.2f\n", intr_rmb);
  162.     if(INTR_TAX > 0.0) {
  163.         printf("after tax interest %.2f\n", intr_rmb*(1 - INTR_TAX));
  164.         intr_rmb = intr_rmb*(1-INTR_TAX);
  165.     }
  166.     total = total + intr_rmb;
  167.     printf("interest gain %.2f\n", intr_rmb);
  168.     printf("base + interest: %.2f\n", total);
  169.     if(last) return;

  170.     printf("-------------------------\n");
  171.     dt = due_time;
  172.     goto loop;
  173. }

  174. main(int argc, char **argv)
  175. {
  176. char temp[32];
  177. int i;
  178. char *cp;
  179. struct tm tm, *tp, *tp1;
  180. struct intr_list l;

  181.     if(argv[1] == 0) {
  182.         printf("Usage: \n\
  183. calc RMBs DEPOSIT_TIME DEPOSIT_LENGTH [WITHDRAW_TIME]\n\
  184. for example:\n\
  185. calc 10000 12/30/2009 3 [12/30/2011] or\n\
  186. calc 10000 2009-12-30 3 2011-12-30\n\
  187. \n\
  188. if no WITHDRAW_TIME given, TODAY is assumed.\n\
  189. if WITHDRAW_TIME is 'd', assuming withdraw will be done in future due time\n");
  190.         return;
  191.     }

  192.     deposit_rmb = atol(argv[1]);
  193.     argv++;


  194.     printf("%s", intrests);


  195.     for(i = 0, cp = intrests; *cp; i++) {
  196.         cp = strchr(cp, '/');
  197.         if(!cp) break;       
  198.         cp -= 2;
  199.         strncpy(temp, cp, 10);
  200.         temp[10] = 0;

  201.         memset(&tm, 0, sizeof(struct tm));
  202.         strptime(temp, "%m/%d/%Y", &tm);
  203.         //tm.tm_year -= 1980;
  204.         cp += 10;
  205.         sscanf(cp, "%f %f %f %f %f %f", &l.intr_temp, &l.intr_half, &l.intr_y1, &l.intr_y2, &l.intr_y3, &l.intr_y5);
  206.         //printf("%s %d ---- %f\n", asctime(&tm), tm.tm_year, l.intr_y5);

  207.         l.from = mktime(&tm);
  208.         intr_list[i] = l;
  209.     }   
  210.     intr_max = i;

  211.     //get deposit time
  212.     strcpy(temp, argv[1]);
  213.     if(strchr(temp, '-')) {
  214.         strptime(temp, "%Y-%m-%d", &tm);
  215.     } else if(strchr(temp, '/')) {
  216.         strptime(temp, "%m/%d/%Y", &tm);
  217.     } else {
  218.         printf("date format is 2011-11-29 or 11/29/2011.\n");
  219.         return;
  220.     }
  221.     deposit_time = mktime(&tm);

  222.     sscanf(argv[2], "%f", &deposit_period);
  223.    
  224.     //get withdraw time
  225.     if(argv[3]) {
  226.         strcpy(temp, argv[3]);
  227.         strptime(temp, "%m/%d/%Y", &tm);
  228.         if(strchr(temp, '-'))
  229.             strptime(temp, "%Y-%m-%d", &tm);

  230.         withdraw_time = mktime(&tm);

  231.         if(!isdigit(argv[3][0])) {  //automatic withdraw at next due time
  232.             int i;
  233.             for(i = 0; i < 16; i++) {       
  234.                 withdraw_time = addtime(deposit_time, i*deposit_period);
  235.                 if(withdraw_time >= time(0)) break;
  236.             }       
  237.             printf("will withdraw in %s\n", yasctime(localtime(&withdraw_time)) );
  238.         }

  239.     } else
  240.         withdraw_time = time(0);


  241.     printf("deposit in (yyyy-mm-dd) %s\t", yasctime(localtime(&deposit_time)));
  242.     printf("deposit length (in year) %.1f\t", deposit_period);
  243.     printf("withdraw in %s\n", yasctime(localtime(&withdraw_time)));

  244.     printf("interest: %.2f\n", get_interest(deposit_time, deposit_period));

  245.     calc_it(deposit_time, deposit_period, withdraw_time);
  246.    
  247. }
复制代码

论坛徽章:
0
发表于 2011-12-15 11:52 |显示全部楼层
也欢迎网友继续改进

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2011-12-15 12:07 |显示全部楼层
利率表从网上自动获取更好{:3_189:}
不过实际用到这工具的机会很少,不会有谁存一大堆的定期,还计较精确的利息是多少

论坛徽章:
0
发表于 2011-12-15 12:10 |显示全部楼层
回复 3# hellioncu


这个利率表是从工行的网站上获取的。
应该准确。

论坛徽章:
0
发表于 2011-12-15 12:13 |显示全部楼层
回复 3# hellioncu


我昨天去银行取款有这个要求。就是要判断一下一个下一记利息周期还没有到期的存单如果现在取了会损失多少钱,还就是看银行算的总数对不对。
网上查了没有好的。
有一个山东一个老师写的,还要注册。
所以自己写一个。

论坛徽章:
0
发表于 2011-12-15 15:29 |显示全部楼层
总的来说对银行应用一点用都没得。俺就是干这个的,嘎嘎。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2011-12-15 15:48 |显示全部楼层
回复  hellioncu


我昨天去银行取款有这个要求。就是要判断一下一个下一记利息周期还没有到期的存单如 ...
思一克 发表于 2011-12-15 12:13



    发现代码中直接用==判断浮点数,没有问题么?{:3_184:}

论坛徽章:
0
发表于 2011-12-15 15:49 |显示全部楼层
1.银行计息按自然日期还是对年对月对日各家银行都没扯清楚,你直接除以365太简单了,要扯皮的。
2.利率随时在变,也许明天你这个程序就算错了,这也是各家网上给出的算法要客户输入利率的原因。当然他们明明有利率表还要客户输利率确实也很蛋疼。
3.你的程序是c的,难道你希望每个用户都整一套C编译环境啊。
4.上次收利息税,各家银行都整怕了,估计现在所有银行的计息程序都将利息税保留到的。你没得。
5.分段计息没考虑,历史上有,现在没得,不保证将来没得。
6.利率表不全。
7.应该设计为根据产品类型回调计息模块较有扩展性。

论坛徽章:
0
发表于 2011-12-15 16:06 |显示全部楼层
现在银行利率都是负数 记不记有啥用。

何况小本日子,多级毛少鸡毛没啥好关心的了。

论坛徽章:
0
发表于 2011-12-15 16:09 |显示全部楼层
总的来说对银行应用一点用都没得。俺就是干这个的,嘎嘎。
blackuhlan 发表于 2011-12-15 15:29



对银行无用。因为银行的计算更精确,比如每月天数不同,等。

但对存款人有用。你做这个的,哪个银行给出的这样的计算工具?在线的和离线的都行?
我查了一下午也没有找到一个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP