In ISO Fortran 90 and later the following BIT INTRINSIC functions are defined:
void bitwise(int a, int b)
integer :: i, j = -1, k = 42 { logical :: a printf("a and b: %d\n", a & b); printf("a or b: %d\n", a | b); i = bit_size(j) ! returns the number of bits in the given INTEGER variable printf("a xor b: %d\n", a ^ b); printf("not a: %d\n", ~a); ! bitwise boolean operations on integers printf("a << n: %d\n", a << b); /* left shift */ i = iand(k, j) ! returns bitwise AND of K and J printf("a >> n: %d\n", a >> b); /* on most platforms: arithmetic right shift */ i = ior(k, j) ! returns bitwise OR of K and J /* convert the signed integer into unsigned, so it will perform logical shift */ i = ieor(k, j) ! returns bitwise EXCLUSIVE OR of K and J unsigned int c = a; i = not(j) ! returns bitwise NOT of J printf("c >> b: %d\n", c >> b); /* logical right shift */ /* there are no rotation operators in C */ ! single-bit integer/logical operations (bit positions are zero-based) return 0; a = btest(i, 4) ! returns logical .TRUE. if bit position 4 of I is 1, .FALSE. if 0 } i = ibclr(k, 8) ! returns value of K with 8th bit position "cleared" (set to 0) i = ibset(k, 13) ! returns value of K with 13th bit position "set" (set to 1) To rotate an integer, you can combine a left shift and a right shift: ! multi-bit integer operations i = ishft(k, j) ! returns value of K shifted by J bit positions, with ZERO fill (right shift if J < 0 and /* rotate x to the right by s bits */ left shift if J > 0). unsigned int rotr(unsigned int x, unsigned int s) i = ishftc(k, j) ! returns value of K shifted CIRCULARLY by J bit positions (right circular shift if J < 0 { and left if J > 0) return (x >> s) | (x << 32 - s); i = ishftc(k, j, 20) ! returns value as before except that ONLY the 20 lowest order (rightmost) bits are } circularly shifted i = ibits(k, 7, 8) ! extracts 8 contiguous bits from K starting at position 7 and returns them as the With a smart enough compiler, the above actually compiles into a single machine bit rotate instruction when possible. E.g. gcc -S on IA32 produced following rightmost bits of an otherwise zero-filled integer. For non-negative K this is assembly code: arithmetically equivalent to: MOD((K / 2**7), 2**8) rotr: The following INTRINSIC ELEMENTAL SUBROUTINE is also defined: movl 4(%esp), %eax ; arg1: x movl 8(%esp), %ecx ; arg2: s rorl %cl, %eax ; right rotate x by s call mvbits(k, 2, 4, j, 0) ! copy a sequence of 4 bits from k starting at bit 2 into j starting at bit 0 ret
program bits_rosetta C++
implicit none Translation of: C call bitwise(14,3) #include <iostream> contains void bitwise(int a, int b) subroutine bitwise(a,b) { implicit none std::cout << "a and b: " << (a & b) << '\n'; // Note: parentheses are needed because & has lower precedence than integer, intent(in):: a,b << character(len=*), parameter :: fmt1 = '(2(a,i10))' std::cout << "a or b: " << (a | b) << '\n'; character(len=*),parameter :: fmt2 = '(3(a,b32.32),i20)' std::cout << "a xor b: " << (a ^ b) << '\n'; std::cout << "not a: " << ~a << '\n'; write(*,fmt1) 'input a=',a,' b=',b std::cout << "a shl b: " << (a << b) << '\n'; // Note: "<<" is used both for output and for left shift write(*,fmt2) 'and : ', a,' & ',b,' = ',iand(a, b),iand(a, b) std::cout << "a shr b: " << (a >> b) << '\n'; // typically arithmetic right shift, but not guaranteed write(*,fmt2) 'or : ', a,' | ',b,' = ',ior(a, b),ior(a, b) unsigned int c = a; write(*,fmt2) 'xor : ', a,' ^ ',b,' = ',ieor(a, b),ieor(a, b) std::cout << "c sra b: " << (c >> b) << '\n'; // logical right shift (guaranteed) write(*,fmt2) 'lsh : ', a,' << ',b,' = ',shiftl(a,b),shiftl(a,b) !since F2008, otherwise use ishft(a, abs(b)) // there are no rotation operators in C++ write(*,fmt2) 'rsh : ', a,' >> ',b,' = ',shiftr(a,b),shiftr(a,b) !since F2008, otherwise use ishft(a, -abs(b)) } write(*,fmt2) 'not : ', a,' ~ ',b,' = ',not(a),not(a) write(*,fmt2) 'rot : ', a,' r ',b,' = ',ishftc(a,-abs(b)),ishftc(a,-abs(b)) C# end subroutine bitwise static void bitwise(int a, int b) end program bits_rosetta { Console.WriteLine("a and b is {0}", a & b); Console.WriteLine("a or b is {0}", a | b); Output Console.WriteLine("a xor b is {0}", a ^ b); Console.WriteLine("not a is {0}", ~a); Console.WriteLine("a lshift b is {0}", a << b); Input a= 14 b= 3 Console.WriteLine("a arshift b is {0}", a >> b); // When the left operand of the >> operator is of a AND : 00000000000000000000000000001110 & 00000000000000000000000000000011 = 00000000000000000000000000000010 2 // signed integral type, the operator performs an OR : 00000000000000000000000000001110 | 00000000000000000000000000000011 = 00000000000000000000000000001111 15 // arithmetic shift right XOR : 00000000000000000000000000001110 ^ 00000000000000000000000000000011 = 00000000000000000000000000001101 13 LSH : 00000000000000000000000000001110 << 00000000000000000000000000000011 = 00000000000000000000000001110000 112 uint c = (uint)a; RSH : 00000000000000000000000000001110 >> 00000000000000000000000000000011 = 00000000000000000000000000000001 1 Console.WriteLine("c rshift b is {0}", c >> b); // When the left operand of the >> operator is of an NOT : 00000000000000000000000000001110 ~ 00000000000000000000000000000011 = 11111111111111111111111111110001 -15 // unsigned integral type, the operator performs a ROT : 00000000000000000000000000001110 ~ 00000000000000000000000000000011 = 11000000000000000000000000000001 -1073741823 // logical shift right there are no rotation // operators in C# }