arith.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* Arithmetic for numbers greater than a long int, for GNU tar.
  2. Copyright (C) 1996, 1997 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the
  5. Free Software Foundation; either version 2, or (at your option) any later
  6. version.
  7. This program is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  10. Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program; if not, write to the Free Software Foundation, Inc.,
  13. 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #include "system.h"
  15. /* common.h is needed to define FATAL_ERROR. It also includes arith.h. */
  16. #include "common.h"
  17. /* GNU tar needs handling numbers exceeding 32 bits, which is the size of
  18. unsigned long ints for many C compilers. This module should provide
  19. machinery for handling at least BITS_PER_TARLONG bits per number. If
  20. `long long' ints are available and are sufficient for the task, they will
  21. be used preferrably.
  22. Russell Cattelan reports 165 Gb single tapes (digital video D2 tapes on
  23. Ampex drives), so requiring 38 bits for the tape length in bytes. He
  24. also reports breaking the terabyte limit with a single file (using SGI
  25. xFS file system over 37 28GB disk arrays attached to a Power Challenge
  26. XL; check out http://www.lcse.umn.edu/ for a picture), so requiring a
  27. little more than 40 bits for the file size in bytes. The POSIX header
  28. structure allows for 12 octal digits to represent file lengths, that is,
  29. up to 36 bits for the byte size of files.
  30. If `long long' is not supported by the compiler, SIZEOF_LONG_LONG will be
  31. set to zero by configure. In this case, or if `long long' ints does not
  32. have enough bits, then huge numbers are rather represented by an array of
  33. longs, with the least significant super-digit at position 0. For making
  34. multiplication and decimal input/output easy, the base of a super-digit
  35. is an exact exponent of 10, and is such that base*base fits in a long. */
  36. #if SUPERDIGIT
  37. /*-------------------------------.
  38. | Check if ACCUMULATOR is zero. |
  39. `-------------------------------*/
  40. int
  41. zerop_tarlong_helper (unsigned long *accumulator)
  42. {
  43. int counter;
  44. for (counter = LONGS_PER_TARLONG - 1; counter >= 0; counter--)
  45. if (accumulator[counter])
  46. return 0;
  47. return 1;
  48. }
  49. /*----------------------------------------------.
  50. | Check if FIRST is strictly less than SECOND. |
  51. `----------------------------------------------*/
  52. int
  53. lessp_tarlong_helper (unsigned long *first, unsigned long *second)
  54. {
  55. int counter;
  56. for (counter = LONGS_PER_TARLONG - 1; counter >= 0; counter--)
  57. if (first[counter] != second[counter])
  58. return first[counter] < second[counter];
  59. return 0;
  60. }
  61. /*----------------------------.
  62. | Reset ACCUMULATOR to zero. |
  63. `----------------------------*/
  64. void
  65. clear_tarlong_helper (unsigned long *accumulator)
  66. {
  67. int counter;
  68. for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
  69. accumulator[counter] = 0;
  70. }
  71. /*----------------------------.
  72. | To ACCUMULATOR, add VALUE. |
  73. `----------------------------*/
  74. void
  75. add_to_tarlong_helper (unsigned long *accumulator, int value)
  76. {
  77. int counter;
  78. if (value < 0)
  79. for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
  80. {
  81. if (accumulator[counter] >= -value)
  82. {
  83. accumulator[counter] += value;
  84. return;
  85. }
  86. accumulator[counter] += value + SUPERDIGIT;
  87. value = -1;
  88. }
  89. else
  90. for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
  91. {
  92. if (accumulator[counter] + value < SUPERDIGIT)
  93. {
  94. accumulator[counter] += value;
  95. return;
  96. }
  97. accumulator[counter] += value - SUPERDIGIT;
  98. value = 1;
  99. }
  100. FATAL_ERROR ((0, 0, _("Arithmetic overflow")));
  101. }
  102. /*--------------------------------.
  103. | Multiply ACCUMULATOR by VALUE. |
  104. `--------------------------------*/
  105. void
  106. mult_tarlong_helper (unsigned long *accumulator, int value)
  107. {
  108. int carry = 0;
  109. int counter;
  110. for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
  111. {
  112. carry += accumulator[counter] * value;
  113. accumulator[counter] = carry % SUPERDIGIT;
  114. carry /= SUPERDIGIT;
  115. }
  116. if (carry)
  117. FATAL_ERROR ((0, 0, _("Arithmetic overflow")));
  118. }
  119. /*----------------------------------------------------------.
  120. | Print the decimal representation of ACCUMULATOR on FILE. |
  121. `----------------------------------------------------------*/
  122. void
  123. print_tarlong_helper (unsigned long *accumulator, FILE *file)
  124. {
  125. int counter = LONGS_PER_TARLONG - 1;
  126. while (counter > 0 && accumulator[counter] == 0)
  127. counter--;
  128. fprintf (file, "%uld", accumulator[counter]);
  129. while (counter > 0)
  130. fprintf (file, TARLONG_FORMAT, accumulator[--counter]);
  131. }
  132. #endif /* SUPERDIGIT */