int64.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:7k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /** file: test.c - test of 64-bit integer stuff
  2. *
  3. *
  4. * 21-jan-1998: David Perkins <dperkins@dsperkins.com>
  5. *
  6. */
  7. #include <config.h>
  8. #include <sys/types.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. #if HAVE_STRING_H
  13. #include <string.h>
  14. #else
  15. #include <strings.h>
  16. #endif
  17. #if HAVE_WINSOCK_H
  18. #include <ip/socket.h>
  19. #endif
  20. #include "asn1.h"
  21. #include "int64.h"
  22. /** divBy10 - divide an unsigned 64-bit integer by 10
  23. *
  24. * call with:
  25. *   u64 - number to be divided
  26. *   pu64Q - location to store quotient
  27. *   puR - location to store remainder
  28. *
  29. */
  30. void
  31. divBy10(U64 u64,
  32. U64 *pu64Q,
  33. unsigned int *puR)  
  34. {
  35.     unsigned long ulT;
  36.     unsigned long ulQ;
  37.     unsigned long ulR;
  38.     /* top 16 bits */
  39.     ulT = (u64.high>>16) & 0x0ffff;
  40.     ulQ = ulT/10;
  41.     ulR = ulT%10;
  42.     pu64Q->high = ulQ<<16;
  43.     /* next 16 */
  44.     ulT = (u64.high & 0x0ffff);
  45. ulT += (ulR<<16);
  46.     ulQ = ulT/10;
  47.     ulR = ulT%10;
  48.     pu64Q->high = pu64Q->high | ulQ;
  49.     /* next 16 */
  50.     ulT = ((u64.low>>16) & 0x0ffff) + (ulR<<16);
  51.     ulQ = ulT/10;
  52.     ulR = ulT%10;
  53.     pu64Q->low = ulQ<<16;
  54.     /* final 16 */
  55.     ulT = (u64.low & 0x0ffff);
  56. ulT += (ulR<<16);
  57.     ulQ = ulT/10;
  58.     ulR = ulT%10;
  59.     pu64Q->low = pu64Q->low | ulQ;
  60.     *puR = (unsigned int)(ulR);
  61. } /* divBy10 */
  62. /** multBy10 - multiply an unsigned 64-bit integer by 10
  63. *
  64. * call with:
  65. *   u64 - number to be multiplied
  66. *   pu64P - location to store product
  67. *
  68. */
  69. void
  70. multBy10(U64 u64,
  71.  U64 *pu64P)
  72. {
  73.     unsigned long ulT;
  74.     unsigned long ulP;
  75.     unsigned long ulK;
  76.     /* lower 16 bits */
  77.     ulT = u64.low & 0x0ffff;
  78.     ulP = ulT * 10;
  79.     ulK = ulP>>16;
  80.     pu64P->low = ulP & 0x0ffff;
  81.     /* next 16 */
  82.     ulT = (u64.low>>16) & 0x0ffff;
  83.     ulP = (ulT * 10) + ulK;
  84.     ulK = ulP>>16;
  85.     pu64P->low = (ulP & 0x0ffff)<<16 | pu64P->low;
  86.     /* next 16 bits */
  87.     ulT = u64.high & 0x0ffff;
  88.     ulP = (ulT * 10) + ulK;
  89.     ulK = ulP>>16;
  90.     pu64P->high = ulP & 0x0ffff;
  91.     /* final 16 */
  92.     ulT = (u64.high>>16) & 0x0ffff;
  93.     ulP = (ulT * 10) + ulK;
  94.     ulK = ulP>>16;
  95.     pu64P->high = (ulP & 0x0ffff)<<16 | pu64P->high;
  96. } /* multBy10 */
  97. /** incrByU16 - add an unsigned 16-bit int to an unsigned 64-bit integer
  98. *
  99. * call with:
  100. *   pu64 - number to be incremented
  101. *   u16 - amount to add
  102. *
  103. */
  104. void
  105. incrByU16(U64 *pu64,
  106.   unsigned int u16)
  107. {
  108.     unsigned long ulT1;
  109.     unsigned long ulT2;
  110.     unsigned long ulR;
  111.     unsigned long ulK;
  112.     /* lower 16 bits */
  113.     ulT1 = pu64->low;
  114.     ulT2 = ulT1 & 0x0ffff;
  115.     ulR = ulT2 + u16;
  116.     ulK = ulR>>16;
  117.     if (ulK == 0) {
  118.         pu64->low = ulT1 + u16;
  119.         return;
  120.     }
  121.     /* next 16 bits */
  122.     ulT2 = (ulT1>>16) & 0x0ffff;
  123.     ulR = ulT2+1;
  124.     ulK = ulR>>16;
  125.     if (ulK == 0) {
  126.         pu64->low = ulT1 + u16;
  127.         return;
  128.     }
  129.    
  130.     /* next 32 - ignore any overflow */
  131.     pu64->low = (ulT1 + u16) & 0x0FFFFFFFFL;
  132.     pu64->high++;
  133. } /* incrByV16 */
  134. void
  135. incrByU32(U64 *pu64,
  136.   unsigned int u32)
  137. {
  138.   unsigned int tmp;
  139.   tmp = pu64->low;
  140.   pu64->low += u32;
  141.   if (pu64->low < tmp)
  142.     pu64->high++;
  143. }
  144. /* pu64out = pu64one - pu64two */
  145. void
  146. u64Subtract(U64 *pu64one,
  147.             U64 *pu64two,
  148.             U64 *pu64out)
  149. {
  150.   if (pu64one->low > pu64two->low) {
  151.     pu64out->low = 0xffffffff - pu64two->low + pu64one->low + 1;
  152.     pu64out->high = pu64one->high - pu64two->high - 1;
  153.   } else {
  154.     pu64out->low = pu64one->low - pu64two->low;
  155.     pu64out->high = pu64one->high - pu64two->high;
  156.   }
  157. }
  158. /** zeroU64 - set an unsigned 64-bit number to zero
  159. *
  160. * call with:
  161. *   pu64 - number to be zero'ed
  162. *
  163. */
  164. void
  165. zeroU64(U64 *pu64)
  166. {
  167.     pu64->low = 0;
  168.     pu64->high = 0;
  169. } /* zeroU64 */
  170. /** isZeroU64 - check if an unsigned 64-bit number is
  171. *
  172. * call with:
  173. *   pu64 - number to be zero'ed
  174. *
  175. */
  176. int
  177. isZeroU64(U64 *pu64)
  178. {
  179.     if ((pu64->low == 0) && (pu64->high == 0))
  180.         return(TRUE);
  181.     else
  182.         return(FALSE);
  183. } /* isZeroU64 */
  184. void
  185. printU64(char * buf, /* char [I64CHARSZ+1]; */
  186.  U64 *pu64)
  187. {
  188.   U64 u64a;
  189.   U64 u64b;
  190.   char aRes [I64CHARSZ+1];
  191.   unsigned int u;
  192.   int j;
  193.   u64a.high = pu64->high;
  194.   u64a.low = pu64->low;
  195.   aRes[I64CHARSZ] = 0;
  196.   for (j = 0; j < I64CHARSZ; j++) {
  197.     divBy10(u64a, &u64b, &u);
  198.     aRes[(I64CHARSZ-1)-j] = (char)('0' + u);
  199.     u64a.high = u64b.high;
  200.     u64a.low = u64b.low;
  201.     if (isZeroU64(&u64a))
  202.       break;
  203.   }
  204.   strcpy(buf, &aRes[(I64CHARSZ-1)-j]);
  205. }
  206. void
  207. printI64(char * buf, /* char [I64CHARSZ+1]; */
  208.  U64 *pu64)
  209. {
  210.   U64 u64a;
  211.   U64 u64b;
  212.   char aRes [I64CHARSZ+1];
  213.   unsigned int u;
  214.   int j, sign=0;
  215.   if (pu64->high & 0x80000000) {
  216.     u64a.high = ~pu64->high;
  217.     u64a.low = ~pu64->low;
  218.     sign = 1;
  219.     incrByU32(&u64a, 1);  /* bit invert and incr by 1 to print 2s complement */
  220.   } else {
  221.     u64a.high = pu64->high;
  222.     u64a.low = pu64->low;
  223.   }
  224.   
  225.   aRes[I64CHARSZ] = 0;
  226.   for (j = 0; j < I64CHARSZ; j++) {
  227.     divBy10(u64a, &u64b, &u);
  228.     aRes[(I64CHARSZ-1)-j] = (char)('0' + u);
  229.     u64a.high = u64b.high;
  230.     u64a.low = u64b.low;
  231.     if (isZeroU64(&u64a))
  232.       break;
  233.   }
  234.   if (sign == 1) {
  235.     aRes[(I64CHARSZ-1)-j-1] = '-';
  236.     strcpy(buf, &aRes[(I64CHARSZ-1)-j-1]);
  237.     return;
  238.   }
  239.   strcpy(buf, &aRes[(I64CHARSZ-1)-j]);
  240. }
  241. int
  242. read64(U64 *i64,
  243.        const char *string)
  244. {
  245.   U64 i64p;
  246.   unsigned int u;
  247.   int sign = 0;
  248.   int ok = 0;
  249.   
  250.   zeroU64(i64);
  251.   if (*string == '-') {
  252.     sign = 1;
  253.     string++;
  254.   }
  255.   
  256.   while (*string && isdigit(*string)) {
  257.     ok = 1;
  258.     u = *string - '0';
  259.     multBy10(*i64, &i64p);
  260.     memcpy(i64, &i64p, sizeof(i64p));
  261.     incrByU16(i64, u);
  262.     string++;
  263.   }
  264.   if (sign) {
  265.     i64->high = ~i64->high;
  266.     i64->low = ~i64->low;
  267.     incrByU16(i64,1);
  268.   }
  269.   return ok;
  270. }
  271.   
  272. #ifdef TESTING
  273. void
  274. main(int argc, char *argv[])
  275. {
  276.     int i;
  277.     int j;
  278.     int l;
  279.     unsigned int u;
  280.     U64 u64a;
  281.     U64 u64b;
  282. #define MXSZ 20
  283.     char aRes[MXSZ+1];
  284.     if (argc < 2) {
  285.         printf("This program takes numbers from the command linen"
  286.                "and prints them out.n"
  287.                "Usage: test <unsignedInt>...n");
  288.         exit(1);
  289.     }
  290.     aRes[MXSZ] = 0;
  291.     for (i = 1; i < argc; i++) {
  292.         l = strlen(argv[i]);
  293.         zeroU64(&u64a);
  294.         for (j = 0; j < l; j++) {
  295.             if (!isdigit(argv[i][j])) {
  296.                 printf("Argument is not a number "%s"n", argv[i]);
  297.                 exit(1);
  298.             }
  299.             u = argv[i][j] - '0';
  300.             multBy10(u64a, &u64b);
  301.             u64a = u64b;
  302.             incrByU16(&u64a, u);
  303.         }
  304.         printf("number "%s" in hex is '%08x%08x'hn",
  305.                 argv[i], u64a.high, u64a.low);
  306.         printf("number is "%s"n", printU64(&u64a));
  307.         for (j = 0; j < MXSZ; j++) {
  308.             divBy10(u64a, &u64b, &u);
  309.             aRes[(MXSZ-1)-j] = (char)('0' + u);
  310.             u64a = u64b;
  311.             if (isZeroU64(&u64a))
  312.                 break;
  313.         }
  314.         printf("number is "%s"n", &aRes[(MXSZ-1)-j]);
  315.     }
  316. exit(0);
  317. } /* main */
  318. #endif /* TESTING */
  319. /* file: test.c */