From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-0.9 required=3.0 tests=BAYES_00,FROM_ADDR_WS autolearn=no autolearn_force=no version=3.4.5-pre1 Date: 24 May 93 17:18:00 GMT From: skates.gsfc.nasa.gov!bambam.gsfc.nasa.gov!nbssal@ames.arc.nasa.gov (Step he Leake) Subject: mixing integer and logical operations Message-ID: <24MAY199312181861@bambam.gsfc.nasa.gov> List-Id: Here is the much-delayed summary of the discussion of bit-wise logical operator s on integers. I was originally vehemently opposed to them, since they violate th e abstraction that integers count things, while an array of bits does not. However, a few good examples of their use in legitimate algorithms have led me to change my mind. On the down side, I also got an example of what I still believe is an improper use. First, the good stuff: >>From DEWAR@SCHONBERG.CS.NYU.EDU (Robert Dewar): Compute: number of bits set to 1 in a word N Method: count := 0; while N != 0 loop count := count + 1; N := N and (N - 1); end loop Here the essential part of the algorithm is the subtraction of 1 from N. This algorithm is used in communications processing (parity checking etc), and it truly mixes integer arithmetic and logical operations. >>From stt@dsd.camb.inmet.com (Tucker Taft): 1) Hashing function Hash(X : String; Mask : Unsigned) return Unsigned is Hash_Value : Unsigned := 0; begin -- Xor all of the characters of X together, shifting left -- one between characters, and preserving only bits on in -- "Mask." for I in X'Range loop Hash_Value := (Hash_Value*2 xor Character'Pos(X(I))) and Mask; end loop; return Hash_Value; end Hash; 2) Jumping up to next multiple of 2**N (X or 2**N-1) + 1 3) Truncating down to nearest multiple of 2**N X and not (2**N-1) These kinds of calculations are quite common in systems programming. Apparently the 9X revision team has fully endorsed this extension, so I'll have to bow to their decision. On the other hand, here's an example of (in my opinion) wrong usage (name omitted because I couldn't parse the return path): subtype MODE_T is C_UNSIGNED_SHORT; -- File mode bits IRWXU : constant MODE_T := 8#700#; -- Read + write + execute, owner IRUSR : constant MODE_T := 8#400#; -- Read permission, owner IWUSR : constant MODE_T := 8#200#; -- Write permission, owner IXUSR : constant MODE_T := 8#100#; -- Execute/search permission, owner IRWXG : constant MODE_T := 8#070#; -- Read + write + execute, group [...] procedure CHMOD (PATH : in STRING; MODE : in MODE_T); [...] CHMOD ("foo", IRUSR or IWUSR or IRGRP); This would be MUCH better done with a record and rep clause: type MODE_FLAGS is record Owner_Read : BOOLEAN; Owner_Write : BOOLEAN; Owner_Execute : BOOLEAN; Group_Read : BOOLEAN; Group_Write : BOOLEAN; Group_Execute : BOOLEAN; System_Read : BOOLEAN; System_Write : BOOLEAN; System_Execute : BOOLEAN; end record; for MODE_FLAGS use record Owner_Read at 1 range 2 .. 2; Owner_Write at 1 range 1 .. 1; -- etc end record; The call to CHMOD would then be: CHMOD ("foo", Mode => (Owner_Read | Owner_Write | Group_Read => TRUE, others => FALSE); I find this much easier to understand. It is mainly the potential misuse in the last example that motivated my origina l objection to mixing integer and logical operations. I guess we'll just have to rely on good software engineers, rather than the language! Stephen Leake NASA Goddard Robotics Lab internet : nbssal@robots.gsfc.nasa.gov