Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

INTEGER (KIND = 1) and CHARACTER (LEN = 1) equivalence?

NotThatItMatters
Beginner
480 Views

I am trying to implement CRC-32 code in Fortran.  The obvious problems with signed and unsigned INTEGER arguments are somewhat bypassed if one makes judicious use of the elemental bit functions (IBSET, IBCLR, IEOR, ...).  The remaining hindrance I am having in implementing this code logic is in the use of CHARACTER arguments.

My application requires a CRC-32 of a CHARACTER string.  If I could interpret this as a string of bytes (INTEGER (1)) then all bit manipulation would be at my disposal.  Do I need to resort to EQUIVALENCE or other non-standard constructs to make this work?

0 Kudos
3 Replies
TimP
Honored Contributor III
480 Views

You could take each character as a short integer in standard Fortran by ICHAR or IACHAR intrinsics which extend them to default integer.

I guess for your purpose you may wish to EQUIVALENCE or TRANSFER to a vectorizable array of INT64.

0 Kudos
NotThatItMatters
Beginner
480 Views

Yes, thank you.  That would effectively handle the bit manipulations.  The signed/unsigned troubles with INTEGER (KIND = 1) could be bypassed entirely by setting the result to an INTEGER (KIND = 4) and doing the bit shifting and XORing with that.

Thanks again.

0 Kudos
NotThatItMatters
Beginner
480 Views

Once again I spoke too soon.  The INTEGER (KIND = 1) is needed if the bits require reversing, which is the case in CRC-32.  So the code snippet I have is the following:

    INTEGER, PARAMETER :: nKIND = 4
    INTEGER (KIND = nKIND) :: ubyte
    INTEGER (KIND = 1) :: sbyte

            ! Bring the next byte into the remainder.
            ubyte = ICHAR(message(byte:byte), nKIND)
            IF (ubyte > 127) THEN
                ! We need to get a signed INTEGER (KIND = 1) to reflect this
                sbyte = INT(ubyte - 256, 1)
            ELSE
                sbyte = INT(ubyte, 1)
            END IF
            sbyte = reflect(sbyte, 8_1, 1)
            IF (sbyte < 0_1) THEN
                ubyte = sbyte + 256
            ELSE
                ubyte = sbyte
            END IF

 

0 Kudos
Reply