home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / math / bit.ada next >
Encoding:
Text File  |  1988-05-03  |  9.7 KB  |  268 lines

  1.  
  2. -------- SIMTEL20 Ada Software Repository Prologue ------------
  3. --                                                           -*
  4. -- Unit name    : Bit_Functions
  5. -- Version      : 1.0
  6. -- Author       : Freeman L. Moore
  7. --              : P.O. Box 801 M/S 8006
  8. --              : Texas Instruments, Inc.
  9. --              : McKinney, Texas   75069
  10. -- DDN Address  : FMOORE%TI-EG@CSNET-RELAY
  11. -- Copyright    : (c) 1985
  12. -- Date created : February 1985
  13. -- Release date : June 1985
  14. -- Last update  : June 1985
  15. -- Machine/System Compiled/Run on :
  16. --                DG MV/1000, Rolm/ADE version 2.20          -*
  17. ---------------------------------------------------------------
  18. --                                                           -*
  19. -- Keywords     : bit functions, shifting, masks
  20. ----------------:
  21. --
  22. -- Abstract     : This package represents a collection of
  23. ----------------: routines which allow the Ada programmer
  24. --              : the ability of perform bit operations on
  25. --              : objects of type INTEGER.  The functions
  26. --              : include the ability to extract/insert bit
  27. --              : fields, shift objects left or right,
  28. --              : and/or objects and create bit masks.
  29. --              :
  30. --                                                           -*
  31. ------------------ Revision history ---------------------------
  32. --                                                           -*
  33. -- DATE         VERSION AUTHOR                  HISTORY
  34. -- Feb 85        1.0    Freeman Moore           original
  35. --                                                           -*
  36. ------------------ Distribution and Copyright -----------------
  37. --                                                           -*
  38. -- This prologue must be included in all copies of this software.
  39. --
  40. -- This software is copyright by the author.
  41. --
  42. -- This software is released to the Ada community.
  43. -- This software is released to the Public Domain (note:
  44. --   software released to the Public Domain is not subject
  45. --   to copyright protection).
  46. -- Restrictions on use or distribution:  NONE
  47. --                                                           -*
  48. ------------------ Disclaimer ---------------------------------
  49. --                                                           -*
  50. -- This software and its documentation are provided "AS IS" and
  51. -- without any expressed or implied warranties whatsoever.
  52. -- No warranties as to performance, merchantability, or fitness
  53. -- for a particular purpose exist.
  54. --
  55. -- Because of the diversity of conditions and hardware under
  56. -- which this software may be used, no warranty of fitness for
  57. -- a particular purpose is offered.  The user is advised to
  58. -- test the software thoroughly before relying on it.  The user
  59. -- must assume the entire risk and liability of using this
  60. -- software.
  61. --
  62. -- In no event shall any person or organization of people be
  63. -- held responsible for any direct, indirect, consequential
  64. -- or inconsequential damages or lost profits.
  65. --                                                           -*
  66. -------------------END-PROLOGUE--------------------------------
  67.  
  68. package BIT_FUNCTIONS is
  69. -- 
  70. --   This package allows the Ada programmer to manipulate the bits
  71. --   within an object of type INTEGER.  The bits are numbers from
  72. --   the right to the left, starting with number zero.
  73. -- 
  74. --           +------------------------+
  75. --           +  15 14 13 ...  3 2 1 0 !
  76. --           +------------------------+
  77. -- 
  78. --      In each routine, the number of bits being manipulated
  79. --      is NBITS.  START_AT identifies the right most bit of NBITS field.
  80. -- 
  81. --      e.g.
  82. --           ...  6 5 4 3 2 1 0
  83. --                    X X X         nbits = 3
  84. --                                  start_at = 2
  85. -- 
  86. -- 
  87.     function BIT_EXTRACT (ITEM, START_AT, NBITS : INTEGER) return INTEGER;
  88. --      Return the bit field extracted from ITEM, as a signed integer;
  89. -- 
  90.     function UBIT_EXTRACT (ITEM, START_AT, NBITS : INTEGER) return INTEGER;
  91. --      return the bit field extracted from ITEM, unsigned integer;
  92. -- 
  93.     function BIT_INSERT (THIS_ITEM, NBITS, INTO_ITEM, START_AT : INTEGER)
  94.                           return INTEGER;
  95. --      insert NBITS from THIS_ITEM into the object INTO_ITEM,
  96. --      with the rightmost bit identified by START_AT.
  97. -- 
  98.     function BIT_REMOVE (ITEM, START_AT, NBITS : INTEGER) return INTEGER;
  99. --      BIT_REMOVE will zero out NBITS of ITEM at position START_AT
  100. -- 
  101.     function SHIFT_LEFT (ITEM, NBITS : INTEGER) return INTEGER;
  102. --      return ITEM shifted left by NBITS
  103. -- 
  104.     function SHIFT_RIGHT (ITEM, NBITS : INTEGER) return INTEGER;
  105. --      return ITEM shifted right by NBITS
  106. -- 
  107.     function BIT_AND (WORD1, WORD2 : INTEGER) return INTEGER;
  108. --      return the AND of the two objects
  109. -- 
  110.     function BIT_OR (WORD1, WORD2 : INTEGER) return INTEGER;
  111. --      return the OR of the two objects
  112. -- 
  113.     function BIT_MASK (NBITS : INTEGER) return INTEGER;
  114. --      return an object with NBITS of one bits, right justified
  115. -- 
  116. end BIT_FUNCTIONS;
  117.  
  118.  
  119. package body BIT_FUNCTIONS is
  120. --
  121. --  Implementation notes:
  122. --      this package uses integer arithmetic (mult by 2 and divide by 2)
  123. --      to accomplish most of the work involved.
  124. --
  125. --  The ideal implementation would be similar to the following:
  126. --
  127. --      OBJECT : INTEGER;
  128. --      type BIT_WORD is array (1..16) of BOOLEAN;
  129. --      pragma PACK (BIT_WORD)
  130. --      BIT_OBJECT : BIT_WORD;
  131. --      for BIT_OBJECT use at OBJECT'ADDRESS;
  132. --
  133. --      This effectively defined BIT_OBJECT as a bit array, physically
  134. --      located at the same memory location as OBJECT.  As a bit array,
  135. --      slices and boolean operations can be used!  Unfortunately,
  136. --      the DG/Rolm ADE software does not support the address rep spec.
  137. --
  138. --
  139.     WORD_SIZE : constant := 16; -- ASSUME 16 BIT WORDS!
  140.  
  141.     function BIT_EXTRACT (ITEM, START_AT, NBITS : INTEGER) return INTEGER is
  142.         TEMP      : INTEGER;
  143.         BIT_VALUE : INTEGER;
  144.         RESULT    : INTEGER;
  145.     begin
  146.         TEMP := SHIFT_RIGHT (ITEM, START_AT);
  147.         BIT_VALUE := (TEMP mod 2 ** NBITS);
  148.  
  149.         if BIT_VALUE <= INTEGER'LAST then
  150.             RESULT := BIT_VALUE;
  151.         else
  152.             RESULT := BIT_VALUE - INTEGER'LAST;
  153.         end if;
  154.  
  155.         return RESULT;
  156.     end BIT_EXTRACT;
  157.  
  158.     function UBIT_EXTRACT (ITEM, START_AT, NBITS : INTEGER) return INTEGER is
  159.         TEMP : INTEGER;
  160.     begin
  161.         TEMP := SHIFT_RIGHT (ITEM, START_AT);
  162.         return TEMP mod (2 ** NBITS);
  163.     end UBIT_EXTRACT;
  164.  
  165.     function BIT_INSERT (THIS_ITEM, NBITS, INTO_ITEM, START_AT : INTEGER)
  166.                           return INTEGER is
  167.         ITEM : INTEGER;
  168.     begin
  169.         ITEM := THIS_ITEM mod (2 ** NBITS); -- restrict value to size
  170.         return BIT_REMOVE (INTO_ITEM, START_AT, NBITS) +
  171.                SHIFT_LEFT (ITEM, START_AT);
  172.     end BIT_INSERT;
  173.  
  174.     function BIT_REMOVE (ITEM, START_AT, NBITS : INTEGER) return INTEGER is
  175.         KEEP : INTEGER := 0;
  176.         TEMP : INTEGER;
  177.     begin
  178.         if START_AT /= 0 then
  179.             KEEP := ITEM mod (2 ** START_AT);
  180.         end if;
  181.  
  182.         TEMP := SHIFT_RIGHT (ITEM, START_AT + NBITS);
  183.         return SHIFT_LEFT (TEMP, START_AT + NBITS) + KEEP;
  184.     end BIT_REMOVE;
  185.  
  186.     function SHIFT_LEFT (ITEM, NBITS : INTEGER) return INTEGER is
  187.     begin
  188.         return ITEM * (2 ** NBITS);
  189.     end SHIFT_LEFT;
  190.  
  191.     function SHIFT_RIGHT (ITEM, NBITS : INTEGER) return INTEGER is
  192.     begin
  193.         return ITEM / (2 ** NBITS);
  194.     end SHIFT_RIGHT;
  195.  
  196.     function BIT_AND (WORD1, WORD2 : INTEGER) return INTEGER is
  197.         SPARE1              : INTEGER := WORD1;
  198.         SPARE2              : INTEGER := WORD2;
  199.         NEW_WORD            : INTEGER := 0;
  200.         BIT1, BIT2, NEW_BIT : INTEGER;
  201.  
  202.     begin
  203. --
  204. --  the approach here to extract a single bit at a time from each
  205. --  word, and then decide upon the logical property.  The loop
  206. --  continues until all bits of the word have been considered,
  207. --  or until the words become zero in the shifting process.
  208. --
  209.  
  210.         for INDEX in 1 .. WORD_SIZE loop
  211.             exit when SPARE1 = 0 and SPARE2 = 0;
  212.             BIT1 := SPARE1 mod 2; -- get rightmost bit
  213.             BIT2 := SPARE2 mod 2;
  214.  
  215.             if BIT1 = 1 and BIT2 = 1 then
  216.                 NEW_BIT := 1;     -- decide upon new bit value
  217.             else
  218.                 NEW_BIT := 0;
  219.             end if;
  220.  
  221.             NEW_WORD := NEW_WORD + SHIFT_LEFT (NEW_BIT, INDEX - 1);
  222.             SPARE1 := SHIFT_RIGHT (SPARE1, 1);
  223.             SPARE2 := SHIFT_RIGHT (SPARE2, 1);
  224.         end loop;
  225.  
  226.         return NEW_WORD;
  227.     end BIT_AND;
  228.  
  229.     function BIT_OR (WORD1, WORD2 : INTEGER) return INTEGER is
  230.         SPARE1              : INTEGER := WORD1;
  231.         SPARE2              : INTEGER := WORD2;
  232.         NEW_WORD            : INTEGER := 0;
  233.         BIT1, BIT2, NEW_BIT : INTEGER;
  234.  
  235.     begin
  236. --  processing is identical to BIT_AND, except the logical test is changed
  237.         for INDEX in 1 .. WORD_SIZE loop
  238.             exit when SPARE1 = 0 and SPARE2 = 0;
  239.             BIT1 := SPARE1 mod 2;
  240.             BIT2 := SPARE2 mod 2;
  241.  
  242.             if BIT1 = 1 or BIT2 = 1 then
  243.                 NEW_BIT := 1;
  244.             else
  245.                 NEW_BIT := 0;
  246.             end if;
  247.  
  248.             NEW_WORD := BIT_INSERT (NEW_BIT, 1, NEW_WORD, INDEX - 1);
  249.             SPARE1 := SHIFT_RIGHT (SPARE1, 1);
  250.             SPARE2 := SHIFT_RIGHT (SPARE2, 1);
  251.         end loop;
  252.  
  253.         return NEW_WORD;
  254.     end BIT_OR;
  255.  
  256.     function BIT_MASK (NBITS : INTEGER) return INTEGER is
  257.         RESULT : INTEGER := 0;
  258.     begin
  259.         for INDEX in 1 .. NBITS loop
  260.             RESULT := RESULT * 2 + 1;
  261.         end loop;
  262.  
  263.         return RESULT;
  264.     end BIT_MASK;
  265.  
  266. end BIT_FUNCTIONS;
  267.  
  268.