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

Documentation clarification: BIT intrinsic

ereisch
New Contributor II
557 Views

https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/a-to-z-reference/a-to-b/bit.html

 

The above documentation notes that the first parameter "Must be in the range 0 (least significant bit) to 31 (most significant bit)", but also notes that the second parameter can be an INTEGER(4) or an INTEGER(8).  Does the function support testing bits 32-63, or does it only support examining the first 32 bytes of a 64-bit operand?

A quick test of an example program shows that it does indeed correctly support examining the upper bits of 64-bit operands, so it appears the documentation is incorrect for the "bitnum" parameter.

It is also unclear as to what happens if you attempt to examine higher-order bits of 32-bit operands:

INTEGER*4   A
A = 32768
IF ( BIT(41, A) ) WRITE(*,*) 'TEST PASSED'

The above compiles and executes successfully (and no output is generated), but is it legal, and/or is it addressing beyond the scope of 'A'?

 

Thanks

0 Kudos
6 Replies
mecej4
Black Belt
542 Views

The documentation on the related subroutines BIC/BIS seems clear enough:

USE IFPORT
CALL BIC
(
bitnum
,
target
)
CALL BIS
(
bitnum
,
target
)
bitnum (Input) INTEGER(4). Bit number to set.
 
     Must be in the range 0 (least significant bit) to 31 (most significant bit) if target is INTEGER(4).
 
     If target is INTEGER(8), bitnum must be in range 0 to 63
 
A more delicate question is whether the compiler is able to catch the error (bit number > 31 for a 4 byte target) in your example code when asked.
 
Would it not be safer to use similar functionality that is covered by the standard, such as BTEST, etc., instead of DEC/Compaq/Intel extensions?
0 Kudos
JohnNichols
Valued Contributor III
500 Views
 program Console31
    use IFPORT

    implicit none
    INTEGER*2   A,B
    Integer*4 pos
    pos = 41
    A = 32767
    B = A + 1

    if(B < 0) then
        write(*,*)" Wrong Integer type"
    else IF ( BTEST(41, A) .eq. 1) then
        WRITE(*,*) 'TEST PASSED'
    else
        write(*,*) "Something bad happened"
    end if

    end program Console31

Should BTEST not test for the integer length?  Just a thought.   

0 Kudos
Steve_Lionel
Black Belt
496 Views

It would be reasonable to do so, but I doubt it happens. 

0 Kudos
JohnNichols
Valued Contributor III
494 Views

No I checked it does not, so I added a simple test.  Of course to test for all integers the else if would get a lot longer.  

Should it not be checked at compile time?  Is this not a bug?

0 Kudos
Steve_Lionel
Black Belt
489 Views

It's not a bug - such checking is not required. You could have a variable with the position and the compiler can't check. The function could check and raise some sort of error.

NAG Fortran does check at compile time:

NAG Fortran Compiler Release 7.1(Hanzomon) Build 7108
Error: t.f90, line 2: POS argument (41) to intrinsic BTEST out of range (0:31)
[NAG Fortran Compiler error termination, 1 error]

I'll note that the test case above gets the arguments in the wrong order.

0 Kudos
mecej4
Black Belt
486 Views

Apart from the other issues that have been discussed, please note that the line of code

 

else IF ( BTEST(41, A) .eq. 1) then

 

is in error since BTEST is of type logical, and its returned value is being compared to the integer constant 1.

0 Kudos
Reply