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

  1. -------- SIMTEL20 Ada Software Repository Prologue ------------
  2. --                                                           -*
  3. -- Unit name    : package LOGICAL
  4. -- Version      : 1.0
  5. -- Author       : Joseph M. Orost
  6. --              : Concurrent Computer Corporation
  7. --              : 106 Apple St.
  8. --              : Tinton Falls, NJ  07724
  9. -- DDN Address  : vax135!petsd!joe@BERKELEY
  10. -- Copyright    : ** not copyright **
  11. -- Date created :  June 1, 1986
  12. -- Release date :  June 13, 1986
  13. -- Last update  :
  14. -- Machine/System Compiled/Run on : CCUR_3200MPS, C3-Ada R00-00
  15. --                                                           -*
  16. ---------------------------------------------------------------
  17. --                                                           -*
  18. -- Keywords     :  LOGICAL OPERATIONS
  19. --
  20. -- Abstract     :  This package provides logical operations
  21. ----------------:  such as AND, OR, XOR, NOT, SHIFT, ROTATE,
  22. ----------------:  on operands of type INTEGER.  It is portable 
  23. ----------------:  to any two's complement machine.  For
  24. ----------------:  increased efficiency, the body can be
  25. ----------------:  re-implemented via PRAGMA interface(assembler.
  26. --                                                           -*
  27. ------------------ Revision history ---------------------------
  28. --                                                           -*
  29. -- DATE         VERSION    AUTHOR                  HISTORY
  30. -- 06/13/86      1.0    Orost           Initial Release
  31. --                                                           -*
  32. ------------------ Distribution and Copyright -----------------
  33. --                                                           -*
  34. -- This software is released to the Ada community.
  35. -- This software is released to the Public Domain (note:
  36. --   software released to the Public Domain is not subject
  37. --   to copyright protection).
  38. -- Restrictions on use or distribution:  NONE
  39. --                                                           -*
  40. ------------------ Disclaimer ---------------------------------
  41. --                                                           -*
  42. -- This software and its documentation are provided "AS IS" and
  43. -- without any expressed or implied warranties whatsoever.
  44. -- No warranties as to performance, merchantability, or fitness
  45. -- for a particular purpose exist.
  46. --
  47. -- Because of the diversity of conditions and hardware under
  48. -- which this software may be used, no warranty of fitness for
  49. -- a particular purpose is offered.  The user is advised to
  50. -- test the software thoroughly before relying on it.  The user
  51. -- must assume the entire risk and liability of using this
  52. -- software.
  53. --
  54. -- In no event shall any person or organization of people be
  55. -- held responsible for any direct, indirect, consequential
  56. -- or inconsequential damages or lost profits.
  57. --                                                           -*
  58. -------------------END-PROLOGUE--------------------------------
  59.  
  60. package logical is
  61.  
  62.    -- return arg rotated count bits.  
  63.    -- If count < 0, rotate is to the right,
  64.    -- else, rotate is to the left.
  65.    function rotate(arg, count : integer) return integer;
  66.  
  67.    -- return arg logically shifted count bits.
  68.    -- bits shifted out either end are lost
  69.    -- If count < 0, shift is to the right,
  70.    -- else, shift is to the left
  71.    function shift(arg, count : integer) return integer;
  72.  
  73.    -- return left XOR right
  74.    function "xor"(left, right : integer) return integer;
  75.  
  76.    --return left AND right
  77.    function "and"(left, right : integer) return integer;
  78.  
  79.    --return left OR right
  80.    function "or" (left, right : integer) return integer;
  81.  
  82.    --return NOT right
  83.    function "not"(right       : integer) return integer;
  84. end logical;
  85. ---
  86. package body logical is
  87.  
  88.    -- These functions work on all two's complement machines
  89.    -- where -integer'last-1 = integer'first
  90.  
  91.    two_to_the_i : array(integer(0)..integer(integer'size-1)) of integer;
  92.  
  93.    --Utility function to rotate left
  94.    function rotate(arg, count : integer) return integer is
  95.       result : integer := arg;
  96.       big      : CONSTANT integer := integer'last/2+1;
  97.       c        : integer := count;
  98.    begin
  99.       if c < 0 then
  100.          c := integer'size + c;
  101.       end if;
  102.       for i in 1..(c MOD integer'size) loop
  103.      if result < 0 then                     -- -16#80000000#..-1
  104.         result := result + big;
  105.         if result >= 0 then
  106.            result := result * 2 - integer'last;
  107.         else
  108.            result := (result + big) * 2 + 1;
  109.         end if;
  110.      elsif result < big then       -- 0 .. 16#3FFFFFFF#
  111.         result := result * 2;
  112.      else                          -- 16#40000000#..16#7FFFFFFF#
  113.         result := (result - big) * 2 - integer'last;
  114.             result := result - 1;
  115.      end if;
  116.       end loop;
  117.       return result;
  118.    end rotate;
  119.    --
  120.    --Utility function to logical shift
  121.    function shift(arg, count : integer) return integer is
  122.       result : integer := arg;
  123.       big      : CONSTANT integer := integer'last/2+1;
  124.       c        : integer;
  125.    begin -- shift
  126.       if count < 0 then                  --shift to the right
  127.          c := -count;
  128.          if c >= integer'size then
  129.             return 0;
  130.          end if;
  131.      if result >= 0 then
  132.         result := result / two_to_the_i(c);
  133.      else
  134.             result := result + integer'last;
  135.         result := (result + 1) / two_to_the_i(c) +
  136.               big / two_to_the_i(c - 1);
  137.      end if;
  138.       elsif count > 0 then                --shift to the left
  139.          if count >= integer'size then
  140.             return 0;
  141.          end if;
  142.          for i in 1..count loop
  143.             if result < 0 then   --top bit gets shifted out
  144.                result := result + integer'last;
  145.                result := result + 1;
  146.             end if;
  147.             if result >= big then
  148.                result := ((result - big) * 2 - integer'last);
  149.                result := result - 1;
  150.             else
  151.                result := result * 2;
  152.             end if;
  153.          end loop;
  154.       end if;
  155.       return result;
  156.    end shift;
  157.    --
  158.    --Utility function to logical shift right 1
  159.    function shift_right_1(arg : integer) return integer is
  160.       result : integer := arg;
  161.       big      : CONSTANT integer := integer'last/2+1;
  162.    begin -- shift_right_1
  163.       if result >= 0 then
  164.      result := result / 2;
  165.       else
  166.          result := result + integer'last;
  167.      result := (result + 1) / 2 + big;
  168.       end if;
  169.       return result;
  170.    end shift_right_1;
  171.    --
  172.    --Utility function to exclusive or
  173.    function "xor"(left, right : integer) return integer is
  174.       result : integer := 0;
  175.       a1 : integer := left;
  176.       a2 : integer := right;
  177.    begin -- "xor"
  178.       for i in integer(0)..integer'size-1 loop
  179.      result := shift_right_1(result);
  180.      if a1 MOD 2 /= a2 MOD 2 then
  181.             result := result - integer'last;
  182.         result := result - 1;
  183.      end if;
  184.      a1 := shift_right_1(a1);
  185.      a2 := shift_right_1(a2);
  186.       end loop;
  187.       return result;
  188.    end "xor";
  189.    --
  190.    --Utility function to and
  191.    function "and"(left, right : integer) return integer is
  192.       result : integer := 0;
  193.       a1 : integer := left;
  194.       a2 : integer := right;
  195.    begin -- "and"
  196.       for i in integer(0)..integer'size-1 loop
  197.      result := shift_right_1(result);
  198.      if (a1 MOD 2) + (a2 MOD 2) = 2 then
  199.             result := result - integer'last;
  200.         result := result - 1;
  201.      end if;
  202.      a1 := shift_right_1(a1);
  203.      a2 := shift_right_1(a2);
  204.       end loop;
  205.       return result;
  206.    end "and";
  207.    --
  208.    --Utility function to or
  209.    function "or"(left, right : integer) return integer is
  210.       result : integer := 0;
  211.       a1 : integer := left;
  212.       a2 : integer := right;
  213.    begin -- "or"
  214.       for i in integer(0)..integer'size-1 loop
  215.      result := shift_right_1(result);
  216.      if (a1 MOD 2) + (a2 MOD 2) /= 0 then
  217.             result := result - integer'last;
  218.         result := result - 1;
  219.      end if;
  220.      a1 := shift_right_1(a1);
  221.      a2 := shift_right_1(a2);
  222.       end loop;
  223.       return result;
  224.    end "or";
  225.    --
  226.    function "not"(right : integer) return integer is
  227.    begin
  228.       if right /= integer'first and then
  229.          right /= integer'first + 1 then
  230.          return (-1)-right;
  231.       else
  232.          return -(right + 1);
  233.       end if;
  234.    end "not";
  235.    --
  236. begin
  237.    for i in two_to_the_i'first..two_to_the_i'last-1 loop
  238.       two_to_the_i(i) := 2**i;
  239.    end loop;
  240.    two_to_the_i(two_to_the_i'last) := (-2)**two_to_the_i'last;
  241. end logical;
  242.