
Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.
You may see other such operations in theBasic Data Operations category, or:
Integer Operations
Arithmetic |Comparison
Boolean Operations
Bitwise |Logical
String Operations
Concatenation |Interpolation |Comparison |Matching
Memory Operations
Pointers & references |Addresses
Write a routine to perform a bitwise AND, OR, and XOR on two integers, a bitwise NOT on the first integer, a left shift, right shift, right arithmetic shift, left rotate, and right rotate.
All shifts and rotates should be done on the first integer with a shift/rotate amount of the second integer.
If any operation is not available in your language, note it.
V x = 10V y = 2print(‘x = ’x)print(‘y = ’y)print(‘NOT x = ’(~x))print(‘x AND y = ’(x [&] y))print(‘x OR y = ’(x [|] y))print(‘x XOR y = ’(x (+) y))print(‘x SHL y = ’(x << y))print(‘x SHR y = ’(x >> y))print(‘x ROL y = ’rotl(x, y))print(‘x ROR y = ’rotr(x, y))
x = 10y = 2NOT x = -11x AND y = 2x OR y = 10x XOR y = 8x SHL y = 40x SHR y = 2x ROL y = 40x ROR y = -2147483646
* Bitwise operations 15/02/2017BITWISE CSECT USING BITWISE,R13 B 72(R15) DC 17F'0' STM R14,R12,12(R13) ST R13,4(R15) ST R15,8(R13) LR R13,R15 L R1,A XDECO R1,PG MVC OP,=CL7'A=' XPRNT OP,L'OP+L'PG L R1,B XDECO R1,PG MVC OP,=CL7'B=' XPRNT OP,L'OP+L'PG* And L R1,A N R1,B XDECO R1,PG MVC OP,=C'A AND B' XPRNT OP,L'OP+L'PG* Or L R1,A O R1,B XDECO R1,PG MVC OP,=C'A OR B' XPRNT OP,L'OP+L'PG* Xor L R1,A X R1,B XDECO R1,PG MVC OP,=C'A XOR B' XPRNT OP,L'OP+L'PG* Not L R1,A X R1,=X'FFFFFFFF' not (by xor -1) XDECO R1,PG MVC OP,=CL7'NOT A' XPRNT OP,L'OP+L'PG* MVC A,=X'80000008' a=-2147483640 (-2^31+8) L R1,A XDECO R1,PG MVC OP,=CL7'A=' XPRNT OP,L'OP+L'PG* shift right arithmetic (on 31 bits) L R1,A SRA R1,3 XDECO R1,PG MVC OP,=C'A SRA 3' XPRNT OP,L'OP+L'PG* shift left arithmetic (on 31 bits) L R1,A SLA R1,3 XDECO R1,PG MVC OP,=C'A SLA 3' XPRNT OP,L'OP+L'PG* shift right logical (on 32 bits) L R1,A SRL R1,3 XDECO R1,PG MVC OP,=C'A SRL 3' XPRNT OP,L'OP+L'PG* shift left logical (on 32 bits) L R1,A SLL R1,3 XDECO R1,PG MVC OP,=C'A SLL 3' XPRNT OP,L'OP+L'PG*RETURN L R13,4(0,R13) LM R14,R12,12(R13) XR R15,R15 BR R14A DC F'21'B DC F'3'OP DS CL7PG DS CL12 YREGS END BITWISE
A= 21B= 3A AND B 1A OR B 23A XOR B 22NOT A -22A= -2147483640A SRA 3 -268435455A SLA 3 -2147483584A SRL 3 268435457A SLL 3 64
Bitwise operations are done using the accumulator and an immediate constant (prefixed with #) or a value at a specified memory location (no #.)
LDA #$05STA temp ;temp equals 5 for the following
LDA #$08AND temp
LDA #$08ORA temp
LDA #$08EOR temp
LDA #$08EOR #255
The 6502 doesn't have arithmetic shift right, but it can be replicated, provided the negative flag is set according to the value in the accumulator.
LDA #$FF CLC ;clear the carry. That way, ROR will not accidentally shift a 1 into the top bit of a positive number BPL SKIP SEC ;if the value in A is negative, setting the carry will ensure that ROR will insert a 1 into bit 7 of A upon rotating.SKIP: ROR
The 6502 can only rotate a value by one, not an arbitrary number. A looping routine is needed for rotates larger than 1.Also, the 6502'sROL andROR rotate instructions both rotate through the carry, unlike the instructions on other architectures with the same name. (68000, x86, and ARM all have a "ROR" command but it doesn't rotate through the carry on those CPUs.)
LDA #$01ROL ;if the carry was set prior to the ROL, A = 3. If the carry was clear, A = 2.
LDA #$01ROR ;if the carry was set prior to the ROR, A = 0x80. If clear, A = 0.
Integer one is assumed to be a, integer two assumed to be b.Each operation affects one or both operands and would not be used sequentially.The end result of each operation resides in a.The shift and rotate operations should likely push psw and pop psw because they affect the carry flag.
; bitwise ANDanla,b; bitwise ORorla,b; bitwise XORxrla,b; bitwise NOTcpla; left shiftincbrrcaloop:rlcaclrcdjnzb,loop; right shiftincbrlcaloop:rrcaclrcdjnzb,loop; arithmetic right shiftpush20incbrlcamov20.0,cloop:rrcamovc,20.0djnzb,looppop20; left rotateincbrraloop:rladjnzb,loop; right rotateincbrlaloop:rradjnzb,loop
MOVAX,0345hMOVBX,0444hANDAX,BX
MOVAX,0345hMOVBX,0444hORAX,BX
MOVAX,0345hMOVBX,0444hXORAX,BX
MOVAX,0345hNOTAX
MOVAX,03hMOVCL,02hSHLAX,CL
MOVAX,03hMOVCL,02hSHRAX,CL
MOVAX,03hMOVCL,02hSARAX,CL
MOVAX,03hMOVCL,02hROLAX,CL
MOVAX,03hMOVCL,02hRORAX,CL
MOVAX,03hMOVCL,02hRCLAX,CL
MOVAX,03hMOVCL,02hRCRAX,CL
Like with most 68000 commands, you can specify a length parameter. Anything outside that length is unaffected by the operation.
MOVE.W#$100,D0MOVE.W#$200,D1AND.WD0,D1
MOVE.W#$100,D0MOVE.W#$200,D1OR.WD0,D1
MOVE.W#$100,D0MOVE.W#$200,D1EOR.WD0,D1
MOVE.W#$100,D0NOT.WD0
MOVE.W#$FF,D0MOVE.W#$04,D1LSL.WD1,D0;shifts 0x00FF left 4 bits
MOVE.W#$FF,D0MOVE.W#$04,D1LSR.WD1,D0;shifts 0x00FF right 4 bits
MOVE.W#$FF00,D0MOVE.W#$04,D1ASR.WD1,D0;shifts 0xFF00 right 4 bits, preserving its sign
MOVE.W#$FF00,D0MOVE.W#$04,D1ROL.WD1,D0
MOVE.W#$FF00,D0MOVE.W#$04,D1ROR.WD1,D0
MOVE.W#$FF00,D0MOVE.W#$04,D1ROXL.WD1,D0
MOVE.W#$FF00,D0MOVE.W#$04,D1ROXR.WD1,D0
/* ARM assembly AARCH64 Raspberry PI 3B *//* program bitwise64.s *//************************************//* Constantes *//************************************//* for this file see task include a file in language AArch64 assembly*/.include "../includeConstantesARM64.inc" /************************************//* Initialized data *//************************************/.dataszMessResultAnd: .asciz "Result of And : \n"szMessResultOr: .asciz "Result of Or : \n"szMessResultEor: .asciz "Result of Exclusif Or : \n"szMessResultNot: .asciz "Result of Not : \n"szMessResultLsl: .asciz "Result of left shift : \n"szMessResultLsr: .asciz "Result of right shift : \n"szMessResultAsr: .asciz "Result of Arithmetic right shift : \n"szMessResultRor: .asciz "Result of rotate right : \n"szMessResultClear: .asciz "Result of Bit Clear : \n"sMessAffBin: .ascii "Register: "sZoneBin: .space 65,' ' .asciz "\n"/************************************//* code section *//************************************/.text.global main main: ldr x0,qAdrszMessResultAnd bl affichageMess mov x0,#5 and x0,x0,#15 bl affichage2 ldr x0,qAdrszMessResultOr bl affichageMess mov x0,#5 orr x0,x0,#15 bl affichage2 ldr x0,qAdrszMessResultEor bl affichageMess mov x0,#5 eor x0,x0,#15 bl affichage2 ldr x0,qAdrszMessResultNot bl affichageMess mov x0,#5 mvn x0,x0 bl affichage2 ldr x0,qAdrszMessResultLsl bl affichageMess mov x0,#5 lsl x0,x0,#1 bl affichage2 ldr x0,qAdrszMessResultLsr bl affichageMess mov x0,#5 lsr x0,x0,#1 bl affichage2 ldr x0,qAdrszMessResultAsr bl affichageMess mov x0,#-5 bl affichage2 mov x0,#-5 asr x0,x0,#1 bl affichage2 ldr x0,qAdrszMessResultRor bl affichageMess mov x0,#5 ror x0,x0,#1 bl affichage2 ldr x0,qAdrszMessResultClear bl affichageMess mov x0,0b1111 bic x0,x0,#0b100 // clear 3ieme bit bl affichage2 mov x0,0b11111 bic x0,x0,#6 // clear 2ieme et 3ième bit ( 6 = 110 binary) bl affichage2100: mov x0, #0 mov x8,EXIT svc 0qAdrszMessResultAnd: .quad szMessResultAndqAdrszMessResultOr: .quad szMessResultOrqAdrszMessResultEor: .quad szMessResultEorqAdrszMessResultNot: .quad szMessResultNotqAdrszMessResultLsl: .quad szMessResultLslqAdrszMessResultLsr: .quad szMessResultLsrqAdrszMessResultAsr: .quad szMessResultAsrqAdrszMessResultRor: .quad szMessResultRorqAdrszMessResultClear: .quad szMessResultClear/******************************************************************//* display register in binary */ /******************************************************************//* x0 contains the register *//* x1 contains the address of receipt area */affichage2: stp x1,lr,[sp,-16]! // save registers ldr x1,qAdrsZoneBin bl conversion2 ldr x0,qAdrsZoneMessBin bl affichageMess ldp x1,lr,[sp],16 // restaur 2 registres ret // retour adresse lr x30 qAdrsZoneBin: .quad sZoneBin qAdrsZoneMessBin: .quad sMessAffBin/******************************************************************//* register conversion in binary */ /******************************************************************//* x0 contains the value *//* x1 contains the address of receipt area */conversion2: stp x2,lr,[sp,-16]! // save registers stp x3,x4,[sp,-16]! // save registers mov x3,64 // position counter of the written character2: // loop tst x0,1 // test first bit lsr x0,x0,#1 // shift right one bit bne 3f mov x2,#48 // bit = 0 => character '0' b 4f3: mov x2,#49 // bit = 1 => character '1' 4: strb w2,[x1,x3] // character in reception area at position counter subs x3,x3,#1 // 0 bits ? bgt 2b // no! loop100: ldp x3,x4,[sp],16 // restaur 2 registres ldp x2,lr,[sp],16 // restaur 2 registres ret // retour adresse lr x30 /***************************************************//* ROUTINES INCLUDE *//***************************************************//* for this file see task include a file in language AArch64 assembly*/.include "../includeARM64.inc"
Result of And :Register: 0000000000000000000000000000000000000000000000000000000000000101Result of Or :Register: 0000000000000000000000000000000000000000000000000000000000001111Result of Exclusif Or :Register: 0000000000000000000000000000000000000000000000000000000000001010Result of Not :Register: 1111111111111111111111111111111111111111111111111111111111111010Result of left shift :Register: 0000000000000000000000000000000000000000000000000000000000001010Result of right shift :Register: 0000000000000000000000000000000000000000000000000000000000000010Result of Arithmetic right shift :Register: 1111111111111111111111111111111111111111111111111111111111111011Register: 1111111111111111111111111111111111111111111111111111111111111101Result of rotate right :Register: 1000000000000000000000000000000000000000000000000000000000000010Result of Bit Clear :Register: 0000000000000000000000000000000000000000000000000000000000001011Register: 0000000000000000000000000000000000000000000000000000000000011001
This works in ABAP 7.40 and above. The missing arithmetic shift operations have been implemented with arithmetic, whereas the logical shift and the rotate operations have been implemented using the built in string functions shift_left and shift_right.
reportz_bitwise_operations.classhex_converterdefinition.public section.class-methods:to_binaryimportinghex_valuetypexreturningvalue(binary_value)typestring,to_decimalimportinghex_valuetypexreturningvalue(decimal_value)typeint4.endclass.classhex_converterimplementation.methodto_binary.data(number_of_bits)=xstrlen(hex_value)*8.donumber_of_bitstimes.get bitsy-indexofhex_valueintodata(bit).binary_value=|{binary_value}{bit}|.enddo.endmethod.methodto_decimal.decimal_value=hex_value.endmethod.endclass.classmissing_bitwise_operationsdefinition.public section.class-methods:arithmetic_shift_leftimportingold_valuetypexchange_withtypexexportingnew_valuetypex,arithmetic_shift_rightimportingold_valuetypexchange_withtypexexportingnew_valuetypex,logical_shift_leftimportingold_valuetypexchange_withtypexexportingnew_valuetypex,logical_shift_rightimportingold_valuetypexchange_withtypexexportingnew_valuetypex,rotate_leftimportingold_valuetypexchange_withtypexexportingnew_valuetypex,rotate_rightimportingold_valuetypexchange_withtypexexportingnew_valuetypex.endclass.classmissing_bitwise_operationsimplementation.methodarithmetic_shift_left.clearnew_value.new_value=old_value*2**change_with.endmethod.methodarithmetic_shift_right.clearnew_value.new_value=old_valuediv2**change_with.endmethod.methodlogical_shift_left.clearnew_value.data(bits)=hex_converter=>to_binary(old_value).data(length_of_bit_sequence)=strlen(bits).bits=shift_left(val=bitsplaces=change_with).whilestrlen(bits)<length_of_bit_sequence.bits=|{bits}0|.endwhile.dostrlen(bits)times.data(index)=sy-index-1.data(current_bit)=bits+index(1).ifcurrent_biteq`1`.set bitsy-indexofnew_value.endif.enddo.endmethod.methodlogical_shift_right.clearnew_value.data(bits)=hex_converter=>to_binary(old_value).data(length_of_bit_sequence)=strlen(bits).bits=shift_right(val=bitsplaces=change_with).whilestrlen(bits)<length_of_bit_sequence.bits=|0{bits}|.endwhile.dostrlen(bits)times.data(index)=sy-index-1.data(current_bit)=bits+index(1).ifcurrent_biteq`1`.set bitsy-indexofnew_value.endif.enddo.endmethod.methodrotate_left.clearnew_value.data(bits)=hex_converter=>to_binary(old_value).bits=shift_left(val=bitscircular=change_with).dostrlen(bits)times.data(index)=sy-index-1.data(current_bit)=bits+index(1).ifcurrent_biteq`1`.set bitsy-indexofnew_value.endif.enddo.endmethod.methodrotate_right.clearnew_value.data(bits)=hex_converter=>to_binary(old_value).bits=shift_right(val=bitscircular=change_with).dostrlen(bits)times.data(index)=sy-index-1.data(current_bit)=bits+index(1).ifcurrent_biteq`1`.set bitsy-indexofnew_value.endif.enddo.endmethod.endclass.start-of-selection.data:atypexlength4value255,btypexlength4value2,result typexlength4.write:|a ->{a},{hex_converter=>to_binary(a)},{hex_converter=>to_decimal(a)}|,/.write:|b ->{b},{hex_converter=>to_binary(b)},{hex_converter=>to_decimal(b)}|,/.result=abit-andb.write:|a & b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.result=abit-orb.write:|a \|b->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.result=abit-xorb.write:|a ^ b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.result=bit-nota.write:|~a ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>arithmetic_shift_left(exportingold_value=bit-notachange_with=bimportingnew_value=result).write:|~a << b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>arithmetic_shift_right(exportingold_value=bit-notachange_with=bimportingnew_value=result).write:|~a >> b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>logical_shift_left(exportingold_value=achange_with=bimportingnew_value=result).write:|a <<< b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>logical_shift_right(exportingold_value=bit-notachange_with=bimportingnew_value=result).write:|~a >>> b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>rotate_left(exportingold_value=bit-notachange_with=bimportingnew_value=result).write:|~a rotl b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.missing_bitwise_operations=>rotate_right(exportingold_value=achange_with=bimportingnew_value=result).write:|a rotr b ->{result},{hex_converter=>to_binary(result)},{hex_converter=>to_decimal(result)}|,/.
a -> 000000FF, 00000000000000000000000011111111, 255b -> 00000002, 00000000000000000000000000000010, 2a & b -> 00000002, 00000000000000000000000000000010, 2a | b -> 000000FF, 00000000000000000000000011111111, 255a ^ b -> 000000FD, 00000000000000000000000011111101, 253~a -> FFFFFF00, 11111111111111111111111100000000, -256~a << b -> FFFFFC00, 11111111111111111111110000000000, -1024~a >> b -> FFFFFFC0, 11111111111111111111111111000000, -64a <<< b -> 000003FC, 00000000000000000000001111111100, 1020~a >>> b -> 3FFFFFC0, 00111111111111111111111111000000, 1073741760~a rotl b -> FFFFFC03, 11111111111111111111110000000011, -1021a rotr b -> C000003F, 11000000000000000000000000111111, -1073741761
Unlisted operations are not available
(defunbitwise(ab)(list(logandab)(logiorab)(logxorab)(lognota)(ashab)(asha(-b))))
BYTE FUNC Not(BYTE a)RETURN (a!$FF)PROC Main() BYTE a=[127],b=[2],res res=a&b PrintF("%B AND %B = %B%E",a,b,res) res=a%b PrintF("%B OR %B = %B%E",a,b,res) res=a!b PrintF("%B XOR %B = %B%E",a,b,res) res=Not(a) PrintF("NOT %B = %B (by %B XOR $FF)%E",a,res,a) res=a RSH b PrintF("%B SHR %B = %B%E",a,b,res) res=a LSH b PrintF("%B SHL %B = %B%E",a,b,res)RETURNScreenshot from Atari 8-bit computer
127 AND 2 = 2127 OR 2 = 127127 XOR 2 = 125NOT 127 = 128 (by 127 XOR $FF)127 SHR 2 = 31127 SHL 2 = 252
ActionScript does not support bitwise rotations.
functionbitwise(a:int,b:int):void{trace("And: ",a&b);trace("Or: ",a|b);trace("Xor: ",a^b);trace("Not: ",~a);trace("Left Shift: ",a<<b);trace("Right Shift(Arithmetic): ",a>>b);trace("Right Shift(Logical): ",a>>>b);}
The following program performs all required operations and prints the resulting values in base 2 for easy checking of the bit values.
withAda.Text_IO,Interfaces;useAda.Text_IO,Interfaces;procedureBitwiseissubtypeByteisUnsigned_8;packageByte_IOis newAda.Text_Io.Modular_IO(Byte);A:constantByte:=2#00011110#;B:constantByte:=2#11110100#;X:constantByte:=128;N:constantNatural:=1;beginPut("A and B = ");Byte_IO.Put(Item=>AandB,Base=>2);New_Line;Put("A or B = ");Byte_IO.Put(Item=>AorB,Base=>2);New_Line;Put("A xor B = ");Byte_IO.Put(Item=>AxorB,Base=>2);New_Line;Put("not A = ");Byte_IO.Put(Item=>notA,Base=>2);New_Line;New_Line(2);Put_Line(Unsigned_8'Image(Shift_Left(X,N)));Put_Line(Unsigned_8'Image(Shift_Right(X,N)));Put_Line(Unsigned_8'Image(Shift_Right_Arithmetic(X,N)));Put_Line(Unsigned_8'Image(Rotate_Left(X,N)));Put_Line(Unsigned_8'Image(Rotate_Right(X,N)));endBitwise;
There is no rotate support built in to Aikido.
function bitwise(a, b){ println("a AND b: " + (a & b)) println("a OR b: "+ (a | b)) println("a XOR b: "+ (a ^ b)) println("NOT a: " + ~a) println("a << b: " + (a << b)) // left shift println("a >> b: " + (a >> b)) // arithmetic right shift println("a >>> b: " + (a >>> b)) // logical right shift}Aside from decimal,ALGOL 68 has 5 different alternative was of representing the number 170:
BEGIN BITS all bits mask = NOT 16r0; LONG BITS long bits mask = LENG all bits mask; PRIO SLC = 8, SRC = 8; # SLC and SRC are not built in, define and overload them here # OP SLC = (BITS b, INT rotate) BITS: b SHL rotate OR b SHR ( bits width - rotate ); OP SRC = (BITS b, INT rotate) BITS: b SHR rotate OR SHORTEN ( long bits mask AND ( LENG b SHL ( bits width - rotate ) ) ); # SRC and SRL are non-standard, but versions are built in to ALGOL 68R's standard prelude # PRIO XOR = 2; OP XOR = (BITS p, q) BITS: p AND NOT q OR NOT p AND q; # XOR is non-standard, but a version is built in to ALGOL 68G's standard prelude # # ALGOL 68 has 5 different ways of representing a BINary BITS - Bases: 2, 4, 8, 16 and flip/flop # FORMAT b5 = IF bits width > 32 THEN $"2r"2r64d," 4r"4r32d,l" 8r"8r22d," 16r"16r16d,l" "gl$ ELSE $"2r"2r32d," 4r"4r16d," 8r"8r11d," 16r"16r8d,l" "gl$ FI; OP BBBBB = (BITS b)[]BITS: (b,b,b,b,b); PROC bitwise = (BITS a, BITS b, INT shift)VOID: ( printf(( $" bits shorths: "gxgl$, bits shorths, "1 plus the number of extra SHORT BITS types", $" bits lengths: "gxgl$, bits lengths, "1 plus the number of extra LONG BITS types", $" max bits: "gl$, max bits, $" long max bits: "gl$, long max bits, $" long long max bits: "gl$, long long max bits, $" bits width: "gxgl$, bits width, "The number of CHAR required to display BITS", $" long bits width: "gxgl$, long bits width, "The number of CHAR required to display LONG BITS", $" long long bits width: "gxgl$, long long bits width, "The number of CHAR required to display LONG LONG BITS", $" bytes shorths: "gxgl$, bytes shorths, "1 plus the number of extra SHORT BYTES types", $" bytes lengths: "gxgl$, bits lengths, "1 plus the number of extra LONG BYTES types", $" bytes width: "gxgl$, bytes width, "The number of CHAR required to display BYTES", $" long bytes width: "gxgl$, long bytes width, "The number of CHAR required to display LONG BYTES" )); printf(($" a: "f(b5)$, BBBBB a)); printf(($" b: "f(b5)$, BBBBB b)); printf(($" a AND b: "f(b5)$, BBBBB(a AND b))); printf(($" a OR b: "f(b5)$, BBBBB(a OR b))); printf(($" a XOR b: "f(b5)$, BBBBB(a XOR b))); printf(($" NOT b: "f(b5)$, BBBBB NOT a)); printf(($" a SHL "d": "f(b5)$, shift, BBBBB(a SHL shift))); printf(($" a SHR "d": "f(b5)$, shift, BBBBB(a SHR shift))); printf(($" a SLC "d": "f(b5)$, shift, BBBBB(a SLC shift))); printf(($" a SRC "d": "f(b5)$, shift, BBBBB(a SRC shift)))COMMENT with original ALGOL 68 character set; printf(($" a AND b: "f(b5)$, BBBBB(a ∧ b))); printf(($" a OR b: "f(b5)$, BBBBB(a ∨ b))); printf(($" NOT b: "f(b5)$, BBBBB ¬ a)); printf(($" a SHL "d": "f(b5)$, shift, BBBBB(a ↑ shift))); printf(($" a SHR "d": "f(b5)$, shift, BBBBB(a ↓ shift)));Also: printf(($" a AND b: "f(b5)$, BBBBB(a /\ b))); printf(($" a OR b: "f(b5)$, BBBBB(a \/ b)));COMMENT ); bitwise(BIN 255, BIN 170, 5)# or using alternate representations for 255 and 170 in BITS #CO bitwise(2r11111111,2r10101010,5); bitwise(4r3333,4r2222,5); bitwise(8r377,8r252,5); bitwise(16rff,16raa,5)END COEND
This is fromALGOL 68 Genie version 3 running on Windows, on other platforms (or with other compilers/interpreters) the number of bits in the various BITS modes and hence the values shown may differ .
bits shorths: +1 1 plus the number of extra SHORT BITS types bits lengths: +2 1 plus the number of extra LONG BITS types max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT long max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT long long max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT bits width: +64 The number of CHAR required to display BITS long bits width: +128 The number of CHAR required to display LONG BITS long long bits width: +128 The number of CHAR required to display LONG LONG BITS bytes shorths: +1 1 plus the number of extra SHORT BYTES types bytes lengths: +2 1 plus the number of extra LONG BYTES types bytes width: +32 The number of CHAR required to display BYTES long bytes width: +256 The number of CHAR required to display LONG BYTES a: 2r0000000000000000000000000000000000000000000000000000000011111111 4r00000000000000000000000000003333 8r0000000000000000000377 16r00000000000000ff FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT b: 2r0000000000000000000000000000000000000000000000000000000010101010 4r00000000000000000000000000002222 8r0000000000000000000252 16r00000000000000aa FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF a AND b: 2r0000000000000000000000000000000000000000000000000000000010101010 4r00000000000000000000000000002222 8r0000000000000000000252 16r00000000000000aa FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF a OR b: 2r0000000000000000000000000000000000000000000000000000000011111111 4r00000000000000000000000000003333 8r0000000000000000000377 16r00000000000000ff FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT a XOR b: 2r0000000000000000000000000000000000000000000000000000000001010101 4r00000000000000000000000000001111 8r0000000000000000000125 16r0000000000000055 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTFTFTFT NOT b: 2r1111111111111111111111111111111111111111111111111111111100000000 4r33333333333333333333333333330000 8r1777777777777777777400 16rffffffffffffff00 TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTFFFFFFFF a SHL 5: 2r0000000000000000000000000000000000000000000000000001111111100000 4r00000000000000000000000001333200 8r0000000000000000017740 16r0000000000001fe0 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTTFFFFF a SHR 5: 2r0000000000000000000000000000000000000000000000000000000000000111 4r00000000000000000000000000000013 8r0000000000000000000007 16r0000000000000007 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTT a SLC 5: 2r0000000000000000000000000000000000000000000000000001111111100000 4r00000000000000000000000001333200 8r0000000000000000017740 16r0000000000001fe0 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTTFFFFF a SRC 5: 2r1111100000000000000000000000000000000000000000000000000000000111 4r33200000000000000000000000000013 8r1740000000000000000007 16rf800000000000007 TTTTTFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTT
Note that an INT can be widened into BITS, and BITS can be widened into an array of BOOL. eg:
# unpack (widen) some data back into an a BOOL array #INT i := 170;BITS j := BIN i;[bits width]BOOL k := j;printf(($g", 8r"8r4d", "8(g)l$, i, j, k[bits width-8+1:]));# now pack some data back into an INT #k[bits width-8+1:] := (FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE);j := bits pack(k);i := ABS j;printf(($g", 8r"8r4d", "8(g)l$, i, j, k[bits width-8+1:]))
Output:
+170, 8r0252, TFTFTFTF +85, 8r0125, FTFTFTFT
% performs bitwise and, or, not, left-shift and right shift on the integers n1 and n2 %% Algol W does not have xor, arithmetic right shift, left rotate or right rotate %procedure bitOperations ( integer value n1, n2 ) ;begin bits b1, b2; % the Algol W bitwse operations operate on bits values, so we first convert the % % integers to bits values using the builtin bitstring procedure % % the results are converted back to integers using the builtin number procedure % % all Algol W bits and integers are 32 bits quantities % b1 := bitstring( n1 ); b2 := bitstring( n2 ); % perform the operaations and display the results as integers % write( n1, " and ", n2, " = ", number( b1 and b2 ) ); write( n1, " or ", n2, " = ", number( b1 or b2 ) ); write( " " , " not ", n1, " = ", number( not b1 ) ); write( n1, " shl ", n2, " = ", number( b1 shl n2 ), " ( left-shift )" ); write( n1, " shr ", n2, " = ", number( b1 shr n2 ), " ( right-shift )" )end bitOPerations ;
Applescript has no bitwise operators. It's probably not the right tool to reach for if you need to work with bits.
If we really do need to use Applescript for bitwise operations, two immediate possibilities come to mind:
First option – 'dialling out to JavaScript for Automation':
This is feasible, (see below) subject to the limitations that:
useAppleScriptversion"2.4"useframework"Foundation"usescriptingadditions-- BIT OPERATIONS FOR APPLESCRIPT (VIA JAVASCRIPT FOR AUTOMATION)-- bitAND :: Int -> Int -> IntonbitAND(x,y)jsOp2("&",x,y)endbitAND-- bitOR :: Int -> Int -> IntonbitOR(x,y)jsOp2("|",x,y)endbitOR-- bitXOr :: Int -> Int -> IntonbitXOR(x,y)jsOp2("^",x,y)endbitXOR-- bitNOT :: Int -> IntonbitNOT(x)jsOp1("~",x)endbitNOT-- (<<) :: Int -> Int -> Inton|<<|(x,y)if31<ythen0elsejsOp2("<<",x,y)endifend|<<|-- Logical right shift-- (>>>) :: Int -> Int -> Inton|>>>|(x,y)jsOp2(">>>",x,y)end|>>>|-- Arithmetic right shift-- (>>) :: Int -> Int -> Inton|>>|(x,y)jsOp2(">>",x,y)end|>>|-- TEST ----------------------------------------------------------onrun-- Using an ObjC interface to Javascript for AutomationsetstrCliptobitWise(255,170)set the clipboard tostrClipstrClipendrun-- bitWise :: Int -> Int -> StringonbitWise(a,b)setlabelsto{"a AND b","a OR b","a XOR b","NOT a",¬"a << b","a >>> b","a >> b"}setxsto{bitAND(a,b),bitOR(a,b),bitXOR(a,b),bitNOT(a),¬|<<|(a,b),|>>>|(a,b),|>>|(a,b)}scriptasBinpropertyarrow:" -> "on|λ|(x,y)justifyRight(8,space,x)&arrow&¬justifyRight(14,space,yastext)&arrow&showBinary(y)end|λ|endscriptunlines({"32 bit signed integers (in two's complement binary encoding)","",¬unlines(zipWith(asBin,¬{"a = "&aastext,"b = "&bastext},{a,b})),"",¬unlines(zipWith(asBin,labels,xs))})endbitWise-- CONVERSIONS AND DISPLAY-- bitsFromInt :: Int -> Either String [Bool]onbitsFromIntLR(x)scriptgoon|λ|(n,d,bools)setxsto{0≠d}&boolsifn>0then|λ|(ndiv2,nmod2,xs)elsexsendifend|λ|endscriptsetatoabs(x)if(2.147483647E+9)<athen|Left|("Integer overflow – maximum is (2 ^ 31) - 1")elsesetbstogo's|λ|(adiv2,amod2,{})if0>xthen|Right|(replicate(32-(lengthofbs),true)&¬binSucc(map(my|not|,bs)))elsesetbstogo's|λ|(adiv2,amod2,{})|Right|(replicate(32-(lengthofbs),false)&bs)endifendifendbitsFromIntLR-- Successor function (+1) for unsigned binary integer-- binSucc :: [Bool] -> [Bool]onbinSucc(bs)scriptsuccon|λ|(a,x)ifathenifxthenTuple(a,false)elseTuple(x,true)endifelseTuple(a,x)endifend|λ|endscriptsettpltomapAccumR(succ,true,bs)if|1|oftplthen{true}&|2|oftplelse|2|oftplendifendbinSucc-- showBinary :: Int -> StringonshowBinary(x)scriptshowBinon|λ|(xs)scriptbCharon|λ|(b)ifbthen"1"else"0"endifend|λ|endscriptmap(bChar,xs)end|λ|endscriptbindLR(mybitsFromIntLR(x),showBin)endshowBinary-- JXA --------------------------------------------------------------------jsOp2 :: String -> a -> b -> conjsOp2(strOp,a,b)bindLR(evalJSLR(unwords({aastext,strOp,bastext})),my|id|)asintegerendjsOp2--jsOp2 :: String -> a -> bonjsOp1(strOp,a)bindLR(evalJSLR(unwords({strOp,aastext})),my|id|)asintegerendjsOp1-- evalJSLR :: String -> Either String aonevalJSLR(strJS)try-- NB if gJSC is global it must be released-- (e.g. set to null) at end of scriptgJSC'sevaluateScriptonerrorsetgJSCtocurrent application'sJSContext'snew()log("new JSC")endtrysetvtounwrap((gJSC'sevaluateScript:(strJS))'stoObject())ifvismissing valuethen|Left|("JS evaluation error")else|Right|(v)endifendevalJSLR-- GENERIC FUNCTIONS ---------------------------------------------------- Left :: a -> Either a bon|Left|(x){type:"Either",|Left|:x,|Right|:missing value}end|Left|-- Right :: b -> Either a bon|Right|(x){type:"Either",|Left|:missing value,|Right|:x}end|Right|-- Tuple (,) :: a -> b -> (a, b)onTuple(a,b){type:"Tuple",|1|:a,|2|:b,length:2}endTuple-- Absolute value.-- abs :: Num -> Numonabs(x)if0>xthen-xelsexendifendabs-- bindLR (>>=) :: Either a -> (a -> Either b) -> Either bonbindLR(m,mf)ifmissing valueis not|Right|ofmthenmReturn(mf)'s|λ|(|Right|ofm)elsemendifendbindLR-- foldr :: (a -> b -> b) -> b -> [a] -> bonfoldr(f,startValue,xs)tellmReturn(f)setvtostartValuesetlngtolengthofxsrepeatwithifromlngto1by-1setvto|λ|(itemiofxs,v,i,xs)endrepeatreturnvendtellendfoldr-- id :: a -> aon|id|(x)xend|id|-- justifyRight :: Int -> Char -> String -> StringonjustifyRight(n,cFiller,strText)ifn>lengthofstrTextthentext-nthru-1of((replicate(n,cFiller)astext)&strText)elsestrTextendifendjustifyRight-- map :: (a -> b) -> [a] -> [b]onmap(f,xs)tellmReturn(f)setlngtolengthofxssetlstto{}repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,i,xs)endrepeatreturnlstendtellendmap-- 'The mapAccumR function behaves like a combination of map and foldr;-- it applies a function to each element of a list, passing an accumulating-- parameter from |Right| to |Left|, and returning a final value of this-- accumulator together with the new list.' (see Hoogle)-- mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])onmapAccumR(f,acc,xs)scripton|λ|(x,a,i)tellmReturn(f)tosetpairto|λ|(|1|ofa,x,i)Tuple(|1|ofpair,(|2|ofpair)&|2|ofa)end|λ|endscriptfoldr(result,Tuple(acc,[]),xs)endmapAccumR-- min :: Ord a => a -> a -> aonmin(x,y)ify<xthenyelsexendifendmin-- Lift 2nd class handler function into 1st class script wrapper-- mReturn :: First-class m => (a -> b) -> m (a -> b)onmReturn(f)ifclassoffisscriptthenfelsescriptproperty|λ|:fendscriptendifendmReturn-- not :: Bool -> Boolon|not|(p)notpend|not|-- Egyptian multiplication - progressively doubling a list, appending-- stages of doubling to an accumulator where needed for binary-- assembly of a target length-- replicate :: Int -> a -> [a]onreplicate(n,a)setoutto{}ifn<1thenreturnoutsetdblto{a}repeatwhile(n>1)if(nmod2)>0thensetouttoout&dblsetnto(ndiv2)setdblto(dbl&dbl)endrepeatreturnout&dblendreplicate-- unlines :: [String] -> Stringonunlines(xs)set{dlm,mytext item delimiters}to¬{mytext item delimiters,linefeed}setstrtoxsastextsetmytext item delimiterstodlmstrendunlines-- unwords :: [String] -> Stringonunwords(xs)set{dlm,mytext item delimiters}to{mytext item delimiters,space}setstoxsastextsetmytext item delimiterstodlmreturnsendunwords-- unwrap :: NSObject -> aonunwrap(objCValue)ifobjCValueismissing valuethenmissing valueelsesetcatocurrent applicationitem1of((ca'sNSArray'sarrayWithObject:objCValue)aslist)endifendunwrap-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]onzipWith(f,xs,ys)setlngtomin(lengthofxs,lengthofys)if1>lngthenreturn{}setlstto{}tellmReturn(f)repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,itemiofys)endrepeatreturnlstendtellendzipWith
32 bit signed integers (in two's complement binary encoding) a = 255 -> 255 -> 00000000000000000000000011111111 b = 170 -> 170 -> 00000000000000000000000010101010 a AND b -> 170 -> 00000000000000000000000010101010 a OR b -> 255 -> 00000000000000000000000011111111 a XOR b -> 85 -> 00000000000000000000000001010101 NOT a -> -256 -> 11111111111111111111111100000000 a << b -> 0 -> 00000000000000000000000000000000 a >>> b -> 0 -> 00000000000000000000000000000000 a >> b -> 0 -> 00000000000000000000000000000000
Second option – writing our own bitwise functions for Applescript:
useAppleScriptversion"2.4"useframework"Foundation"usescriptingadditions-- BITWISE OPERATIONS FOR APPLESCRIPT ----------------------------------------- bitAND :: Int -> Int -> IntonbitAND(x,y)bitOp2(my|and|,x,y)endbitAND-- bitOR :: Int -> Int -> IntonbitOR(x,y)bitOp2(my|or|,x,y)endbitOR-- bitXOr :: Int -> Int -> IntonbitXOR(x,y)bitOp2(myxor,x,y)endbitXOR-- bitNOT :: Int -> IntonbitNOT(x)scriptnotBitson|λ|(xs)bindLR(intFromBitsLR(map(my|not|,xs)),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(x),notBits)endbitNOT-- (<<) :: Int -> Int -> Inton|<<|(a,b)scriptlogicLshifton|λ|(bs)bindLR(intFromBitsLR(take(32,drop(b,bs)&replicate(b,false))),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(a),logicLshift)end|<<|-- Logical right shift-- (>>>) :: Int -> Int -> Inton|>>>|(a,b)scriptlogicRShifton|λ|(bs)bindLR(intFromBitsLR(take(32,replicate(b,false)&drop(b,bs))),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(a),logicRShift)end|>>>|-- Arithmetic right shift-- (>>) :: Int -> Int -> Inton|>>|(a,b)scriptarithRShifton|λ|(bs)if0<lengthofbsthensetsigntoitem1ofbselsesetsigntofalseendifbindLR(intFromBitsLR(take(32,replicate(b,sign)&drop(b,bs))),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(a),arithRShift)end|>>|-- bitRotL :: Int -> Int -> IntonbitRotL(a,b)scriptlRoton|λ|(bs)bindLR(intFromBitsLR(rotate(-b,bs)),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(a),lRot)endbitRotL-- bitRotR :: Int -> Int -> IntonbitRotR(a,b)scriptrRoton|λ|(bs)bindLR(intFromBitsLR(rotate(b,bs)),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(a),rRot)endbitRotR-- TEST ----------------------------------------------------------------- bitWise :: Int -> Int -> StringonbitWise(a,b)setlabelsto{"a AND b","a OR b","a XOR b","NOT a",¬"a << b","a >>> b","a >> b","ROTL a b","ROTR a b"}setxsto{bitAND(a,b),bitOR(a,b),bitXOR(a,b),bitNOT(a),¬|<<|(a,b),|>>>|(a,b),|>>|(a,b),bitRotL(a,b),bitRotR(a,b)}scriptasBinpropertyarrow:" -> "on|λ|(x,y)justifyRight(8,space,x)&arrow&¬justifyRight(14,space,yastext)&arrow&showBinary(y)end|λ|endscriptunlines({"32 bit signed integers (in two's complement binary encoding)","",¬unlines(zipWith(asBin,¬{"a = "&aastext,"b = "&bastext},{a,b})),"",¬unlines(zipWith(asBin,labels,xs))})endbitWiseonrun-- Assuming 32 bit signed integers (in two's complement binary encoding)setstrCliptobitWise(255,170)set the clipboard tostrClipstrClipendrun-- BINARY INTEGER CONVERSIONS AND DISPLAY -------------------------------------------------------------------- bitsFromInt :: Int -> Either String [Bool]onbitsFromIntLR(x)scriptgoon|λ|(n,d,bools)setxsto{0≠d}&boolsifn>0then|λ|(ndiv2,nmod2,xs)elsexsendifend|λ|endscriptsetatoabs(x)if(2.147483647E+9)<athen|Left|("Integer overflow – maximum is (2 ^ 31) - 1")elsesetbstogo's|λ|(adiv2,amod2,{})if0>xthen|Right|(replicate(32-(lengthofbs),true)&¬binSucc(map(my|not|,bs)))elsesetbstogo's|λ|(adiv2,amod2,{})|Right|(replicate(32-(lengthofbs),false)&bs)endifendifendbitsFromIntLR-- intFromBitsLR :: [Bool] -> Either String IntonintFromBitsLR(xs)scriptbitSumon|λ|(x,a,i)ifxthena+(2^(31-i))elseaendifend|λ|endscriptsetlngBitstolengthofxsif32<lngBitsthen|Left|("Applescript limited to signed 32 bit integers")elseif1>lngBitsthen|Right|(0asinteger)elsesetbitsto(restofxs)ifitem1ofxsthen|Right|(0-foldr(bitSum,1,map(my|not|,bits))asinteger)else|Right|(foldr(bitSum,0,bits)asinteger)endifendifendintFromBitsLR-- showBinary :: Int -> StringonshowBinary(x)scriptshowBinon|λ|(xs)scriptbCharon|λ|(b)ifbthen"1"else"0"endifend|λ|endscriptmap(bChar,xs)end|λ|endscriptbindLR(mybitsFromIntLR(x),showBin)endshowBinary-- bitOp2 :: ((Bool -> Bool -> Bool) -> Int -> Int -> IntonbitOp2(f,x,y)scriptyBitson|λ|(bitX)scriptzipOpon|λ|(bitY)bitZipWithLR(f,bitX,bitY)end|λ|endscriptbindLR(bindLR(bindLR(bitsFromIntLR(y),¬zipOp),myintFromBitsLR),my|id|)end|λ|endscriptbindLR(bitsFromIntLR(x),yBits)endbitOp2-- bitZipWithLR :: ((a, b) -> c ) -> [Bool] -> [Bool] -> Either String [(Bool, Bool)]onbitZipWithLR(f,xs,ys)setintXtolengthofxssetintYtolengthofyssetintMaxtomax(intX,intY)if33>intMaxthenifintX>intYthenset{bxs,bys}to{xs,ys&replicate(intX-intY,false)}elseset{bxs,bys}to{xs&replicate(intY-intX,false),ys}endiftellmReturn(f)setlstto{}repeatwithifrom1tointMaxsetendoflstto|λ|(itemiofbxs,itemiofbys)endrepeatreturn|Right|(lst)endtellelse|Left|("Above maximum of 32 bits")endifendbitZipWithLR-- Successor function (+1) for unsigned binary integer-- binSucc :: [Bool] -> [Bool]onbinSucc(bs)scriptsuccon|λ|(a,x)ifathenifxthenTuple(a,false)elseTuple(x,true)endifelseTuple(a,x)endifend|λ|endscriptsettpltomapAccumR(succ,true,bs)if|1|oftplthen{true}&|2|oftplelse|2|oftplendifendbinSucc-- BOOLEANS ------------------------------------------------------ |or| :: Bool -> Bool -> Boolon|or|(x,y)xoryend|or|-- |and| :: Bool -> Bool -> Boolon|and|(x,y)xandyend|and|-- xor :: Bool -> Bool -> Boolonxor(x,y)(xory)andnot(xandy)endxor-- not :: Bool -> Boolon|not|(p)notpend|not|-- GENERAL ------------------------------------------------------ Right :: b -> Either a bon|Right|(x){type:"Either",|Left|:missing value,|Right|:x}end|Right|-- Left :: a -> Either a bon|Left|(x){type:"Either",|Left|:x,|Right|:missing value}end|Left|-- Tuple (,) :: a -> b -> (a, b)onTuple(a,b){type:"Tuple",|1|:a,|2|:b,length:2}endTuple-- Absolute value.-- abs :: Num -> Numonabs(x)if0>xthen-xelsexendifendabs-- bindLR (>>=) :: Either a -> (a -> Either b) -> Either bonbindLR(m,mf)ifmissing valueis not|Right|ofmthenmReturn(mf)'s|λ|(|Right|ofm)elsemendifendbindLR-- drop :: Int -> [a] -> [a]-- drop :: Int -> String -> Stringondrop(n,xs)ifclassofxsis notstringthenifn<lengthofxsthenitems(1+n)thru-1ofxselse{}endifelseifn<lengthofxsthentext(1+n)thru-1ofxselse""endifendifenddrop-- foldr :: (a -> b -> b) -> b -> [a] -> bonfoldr(f,startValue,xs)tellmReturn(f)setvtostartValuesetlngtolengthofxsrepeatwithifromlngto1by-1setvto|λ|(itemiofxs,v,i,xs)endrepeatreturnvendtellendfoldr-- id :: a -> aon|id|(x)xend|id|-- justifyRight :: Int -> Char -> String -> StringonjustifyRight(n,cFiller,strText)ifn>lengthofstrTextthentext-nthru-1of((replicate(n,cFiller)astext)&strText)elsestrTextendifendjustifyRight-- map :: (a -> b) -> [a] -> [b]onmap(f,xs)tellmReturn(f)setlngtolengthofxssetlstto{}repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,i,xs)endrepeatreturnlstendtellendmap-- 'The mapAccumR function behaves like a combination of map and foldr;-- it applies a function to each element of a list, passing an accumulating-- parameter from |Right| to |Left|, and returning a final value of this-- accumulator together with the new list.' (see Hoogle)-- mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])onmapAccumR(f,acc,xs)scripton|λ|(x,a,i)tellmReturn(f)tosetpairto|λ|(|1|ofa,x,i)Tuple(|1|ofpair,(|2|ofpair)&|2|ofa)end|λ|endscriptfoldr(result,Tuple(acc,[]),xs)endmapAccumR-- max :: Ord a => a -> a -> aonmax(x,y)ifx>ythenxelseyendifendmax-- min :: Ord a => a -> a -> aonmin(x,y)ify<xthenyelsexendifendmin-- Lift 2nd class handler function into 1st class script wrapper-- mReturn :: First-class m => (a -> b) -> m (a -> b)onmReturn(f)ifclassoffisscriptthenfelsescriptproperty|λ|:fendscriptendifendmReturn-- Egyptian multiplication - progressively doubling a list, appending-- stages of doubling to an accumulator where needed for binary-- assembly of a target length-- replicate :: Int -> a -> [a]onreplicate(n,a)setoutto{}ifn<1thenreturnoutsetdblto{a}repeatwhile(n>1)if(nmod2)>0thensetouttoout&dblsetnto(ndiv2)setdblto(dbl&dbl)endrepeatreturnout&dblendreplicate-- rotate :: Int -> [a] -> [a]onrotate(n,xs)setlngtolengthofxsif0>nthensetdto(-n)modlngelsesetdtolng-(nmodlng)endifdrop(d,xs)&take(d,xs)endrotate-- take :: Int -> [a] -> [a]-- take :: Int -> String -> Stringontake(n,xs)ifclassofxsisstringthenif0<nthentext1thrumin(n,lengthofxs)ofxselse""endifelseif0<nthenitems1thrumin(n,lengthofxs)ofxselse{}endifendifendtake-- unlines :: [String] -> Stringonunlines(xs)set{dlm,mytext item delimiters}to¬{mytext item delimiters,linefeed}setstrtoxsastextsetmytext item delimiterstodlmstrendunlines-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]onzipWith(f,xs,ys)setlngtomin(lengthofxs,lengthofys)if1>lngthenreturn{}setlstto{}tellmReturn(f)repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,itemiofys)endrepeatreturnlstendtellendzipWith
32 bit signed integers (in two's complement binary encoding) a = 255 -> 255 -> 00000000000000000000000011111111 b = 170 -> 170 -> 00000000000000000000000010101010 a AND b -> 170 -> 00000000000000000000000010101010 a OR b -> 255 -> 00000000000000000000000011111111 a XOR b -> 85 -> 00000000000000000000000001010101 NOT a -> -256 -> 11111111111111111111111100000000 a << b -> 0 -> 00000000000000000000000000000000 a >>> b -> 0 -> 00000000000000000000000000000000 a >> b -> 0 -> 00000000000000000000000000000000ROTL a b -> 261120 -> 00000000000000111111110000000000ROTR a b -> 1.06954752E+9 -> 00111111110000000000000000000000
Athird option is the mathematical one, although it still involves looping through the hypothetical bits where two numbers are involved, unless I've missed a trick. The handlers below all assume positive number inputs (except forarithmeticRightShift()) and attempt to return results of class integer. The "hi bits" of numbers which don't fit the specified register sizes are discarded.
onbitwiseAND(n1,n2,registerSize)setoutto0-- Multiplying equivalent bit values by each other gives 1 where they're both 1 and 0 otherwise.repeatwithifrom0toregisterSize-1tell(2^i)tosetouttoout+(n1divit)*(n2divit)mod2*itendrepeatreturnoutdiv1endbitwiseANDonbitwiseOR(n1,n2,registerSize)setoutto0-- Adding bit values plus a further 1 gives a carry of 1 if either or both values are 1, but not if they're both 0.repeatwithifrom0toregisterSize-1tell(2^i)tosetouttoout+(n1divitmod2+n2divitmod2+1)div2*itendrepeatreturnoutdiv1endbitwiseORonbitwiseXOR(n1,n2,registerSize)setoutto0-- Adding bit values gives 1 if they're different and 0 (with or without a carry) if they're both the same.repeatwithifrom0toregisterSize-1tell(2^i)tosetouttoout+(n1divit+n2divit)mod2*itendrepeatreturnoutdiv1endbitwiseXORonbitwiseNOT(n,registerSize)-- Subtract n from an all-1s value (ie. from 1 less than 2 ^ registerSize).tell(2^registerSize)toreturn(it-1-nmodit)div1endbitwiseNOTonleftShift(n,shift,registerSize)-- Multiply by 2 ^ shift and lose any bits beyond the left of the register.returnn*(2^shift)mod(2^registerSize)div1endleftShiftonrightShift(n,shift,registerSize)-- Divide by 2 ^ shift and lose any bits beyond the right of the register.returnnmod(2^registerSize)div(2^shift)endrightShiftonarithmeticRightShift(n,shift,registerSize)setntonmod(2^registerSize)-- If the number's positive and notionally sets the sign bit, reinterpret it as a negative.tell(2^(registerSize-1))toif(n≥it)thensetntonmodit-it-- Right shift by the appropriate amountsetouttondiv(2^shift)-- If the result for a negative is 0, change it to -1.if((n<0)and(outis0))thensetoutto-1returnoutendarithmeticRightShiftonleftRotate(n,shift,registerSize)-- Cut the register at the appropriate point, left shift the right side and right shift the left by the appropriate amounts.setshifttoshiftmod(registerSize)returnleftShift(n,shift,registerSize)+rightShift(n,registerSize-shift,registerSize)endleftRotateonrightRotate(n,shift,registerSize)-- As left rotate, but applying the shift amounts to the opposite sides.setshifttoshiftmodregisterSizereturnrightShift(n,shift,registerSize)+leftShift(n,registerSize-shift,registerSize)endrightRotatebitwiseAND(92,7,16)--> 4bitwiseOR(92,7,16)--> 95bitwiseXOR(92,7,16)--> 91bitwiseNOT(92,16)--> 64453bitwiseNOT(92,8)--> 163bitwiseNOT(92,32)--> 4.294967203E+9leftShift(92,7,16)--> 11776leftShift(92,7,8)--> 0rightShift(92,7,16)--> 0arithmeticRightShift(92,7,16)--> 0arithmeticRightShift(-92,7,16)--> -1leftRotate(92,7,8)--> 46rightRotate(92,7,8)--> 184rightRotate(92,7,16)--> 47104
/* ARM assembly Raspberry PI *//* program binarydigit.s *//* Constantes */.equ STDOUT, 1.equ WRITE, 4.equ EXIT, 1/* Initialized data */.dataszMessResultAnd: .asciz "Result of And : \n"szMessResultOr: .asciz "Result of Or : \n"szMessResultEor: .asciz "Result of Exclusif Or : \n"szMessResultNot: .asciz "Result of Not : \n"szMessResultLsl: .asciz "Result of left shift : \n"szMessResultLsr: .asciz "Result of right shift : \n"szMessResultAsr: .asciz "Result of Arithmetic right shift : \n"szMessResultRor: .asciz "Result of rotate right : \n"szMessResultRrx: .asciz "Result of rotate right with extend : \n"szMessResultClear: .asciz "Result of Bit Clear : \n"sMessAffBin: .ascii "Register value : "sZoneBin: .space 36,' ' .asciz "\n"/* code section */.text.global main main: /* entry of program */ push {fp,lr} /* save des 2 registres */ ldr r0,iAdrszMessResultAnd bl affichageMess mov r0,#5 and r0,#15 bl affichage2 ldr r0,iAdrszMessResultOr bl affichageMess mov r0,#5 orr r0,#15 bl affichage2 ldr r0,iAdrszMessResultEor bl affichageMess mov r0,#5 eor r0,#15 bl affichage2 ldr r0,iAdrszMessResultNot bl affichageMess mov r0,#5 mvn r0,r0 bl affichage2 ldr r0,iAdrszMessResultLsl bl affichageMess mov r0,#5 lsl r0,#1 bl affichage2 ldr r0,iAdrszMessResultLsr bl affichageMess mov r0,#5 lsr r0,#1 bl affichage2 ldr r0,iAdrszMessResultAsr bl affichageMess mov r0,#-5 bl affichage2 mov r0,#-5 asr r0,#1 bl affichage2 ldr r0,iAdrszMessResultRor bl affichageMess mov r0,#5 ror r0,#1 bl affichage2 ldr r0,iAdrszMessResultRrx bl affichageMess mov r0,#5 mov r1,#15 rrx r0,r1 bl affichage2ldr r0,iAdrszMessResultClear bl affichageMessmov r0,#5 bic r0,#0b100 @ clear 3ieme bit bl affichage2bic r0,#4 @ clear 3ieme bit ( 4 = 100 binary) bl affichage2100: /* standard end of the program */ mov r0, #0 @ return code pop {fp,lr} @restaur 2 registers mov r7, #EXIT @ request to exit program swi 0 @ perform the system calliAdrszMessResultAnd: .int szMessResultAndiAdrszMessResultOr: .int szMessResultOriAdrszMessResultEor: .int szMessResultEoriAdrszMessResultNot: .int szMessResultNotiAdrszMessResultLsl: .int szMessResultLsliAdrszMessResultLsr: .int szMessResultLsriAdrszMessResultAsr: .int szMessResultAsriAdrszMessResultRor: .int szMessResultRoriAdrszMessResultRrx: .int szMessResultRrxiAdrszMessResultClear: .int szMessResultClear/******************************************************************//* register display in binary */ /******************************************************************//* r0 contains the register */affichage2: push {r0,lr} /* save registers */ push {r1-r5} /* save others registers */ mrs r5,cpsr /* saves state register in r5 */ ldr r1,iAdrsZoneBin mov r2,#0 @ read bit position counter mov r3,#0 @ position counter of the written character1: @ loop lsls r0,#1 @ left shift with flags movcc r4,#48 @ flag carry off character '0' movcs r4,#49 @ flag carry on character '1' strb r4,[r1,r3] @ character -> display zone add r2,r2,#1 @ + 1 read bit position counter add r3,r3,#1 @ + 1 position counter of the written character cmp r2,#8 @ 8 bits read addeq r3,r3,#1 @ + 1 position counter of the written character cmp r2,#16 @ etc addeq r3,r3,#1 cmp r2,#24 addeq r3,r3,#1 cmp r2,#31 @ 32 bits shifted ? ble 1b @ no -> loop ldr r0,iAdrsZoneMessBin @ address of message result bl affichageMess @ display result 100: msr cpsr,r5 /*restaur state register */ pop {r1-r5} /* restaur others registers */ pop {r0,lr} bx lriAdrsZoneBin: .int sZoneBin iAdrsZoneMessBin: .int sMessAffBin/******************************************************************//* display text with size calculation */ /******************************************************************//* r0 contains the address of the message */affichageMess: push {fp,lr} /* save registres */ push {r0,r1,r2,r7} /* save others registres */ mov r2,#0 /* counter length */1: /* loop length calculation */ ldrb r1,[r0,r2] /* read octet start position + index */ cmp r1,#0 /* if 0 its over */ addne r2,r2,#1 /* else add 1 in the length */ bne 1b /* and loop */ /* so here r2 contains the length of the message */ mov r1,r0 /* address message in r1 */ mov r0,#STDOUT /* code to write to the standard output Linux */ mov r7, #WRITE /* code call system write */ swi #0 /* call systeme */ pop {r0,r1,r2,r7} /* restaur others registres */ pop {fp,lr} /* restaur des 2 registres */ bx lr /* return */a:255b:2print[a"AND"b"="andab]print[a"OR"b"="orab]print[a"XOR"b"="xorab]print["NOT"a"="nota]print[a"SHL"b"="shlab]print[a"SHR"b"="shrab]
255 AND 2 = 2 255 OR 2 = 255 255 XOR 2 = 253 NOT 255 = -256 255 SHL 2 = 1020 255 SHR 2 = 63
bitwise(3,4)bitwise(a,b){MsgBox%"a and b: ".a&bMsgBox%"a or b: ".a|bMsgBox%"a xor b: ".a^bMsgBox%"not a: ".~a ; treated as unsigned integerMsgBox%"a << b: ".a<<b ; left shiftMsgBox%"a >> b: ".a>>b ; arithmetic right shift}
No arithmetic shift.
bitwise(255,5)Funcbitwise($a,$b)MsgBox(1,'',_$a&" AND "&$b&": "&BitAND($a,$b)&@CRLF&_$a&" OR "&$b&": "&BitOR($a,$b)&@CRLF&_$a&" XOR "&$b&": "&BitXOR($a,$b)&@CRLF&_"NOT "&$a&": "&BitNOT($a)&@CRLF&_$a&" SHL "&$b&": "&BitShift($a,$b*-1)&@CRLF&_$a&" SHR "&$b&": "&BitShift($a,$b)&@CRLF&_$a&" ROL "&$b&": "&BitRotate($a,$b)&@CRLF&_$a&" ROR "&$b&": "&BitRotate($a,$b*-1)&@CRLF)EndFunc
255 AND 5: 5255 OR 5: 255255 XOR 5: 250NOT 255: -256255 SHL 5: 8160255 SHR 5: 7255 ROL 5: 8160255 ROR 5: 63495
Standard awk does not have bitwise operators. Gawk has built-in functions for many bitwise operations. No rotation of bits.
BEGIN{n=11p=1printn" or "p" = "or(n,p)printn" and "p" = "and(n,p)printn" xor "p" = "xor(n,p)printn" << "p" = "lshift(n,p)# left shiftprintn" >> "p" = "rshift(n,p)# right shiftprintf"not %d = 0x%x\n",n,compl(n)# bitwise complement}
OpenBSD/usr/bin/awk (a variant ofnawk) has these same functions, with a few differences. Gawk uses 53-bit unsigned integers, but OpenBSD awk uses 32-bit signed integers. Therefore Gawk printsnot 11 = 0x1ffffffffffff4, but OpenBSD awk printsnot 11 = 0xfffffff4.
Lbl BITSr₁→Ar₂→BDisp "AND:",A·B▶Dec,iDisp "OR:",AᕀB▶Dec,iDisp "XOR:",A▫B▶Dec,iDisp "NOT:",not(A)ʳ▶Dec,i.No language support for shifts or rotationsReturn
Note that the symbols for AND, OR, and XOR are the stat plot marks near the bottom of the Catalog.
In Babel, we prefix the logic operators with a 'c' to denote that they are C-style operations, that is, they are word-width operations, not arbitrary size operations. The following program combines the numbers 5 and 9 using the various bitwise operators and then displays the results.
({5 9}) ({cand} {cor} {cnor} {cxor} {cxnor} {shl} {shr} {ashr} {rol}) cart ! {give <- cp -> compose !} over ! {eval} over ! {;} each[val 0x1 ][val 0xd ][val 0xfffffff7 ][val 0xc ][val 0xfffffff3 ][val 0xa00 ][val 0x0 ][val 0x0 ][val 0xa00 ]
The cnot operator works on just one operand:
9 cnot ;
[val 0xfffffff6 ]
QuickBasic does not have shift or rotate operations defined. Here are the logical operations:
SUBbitwise(a,b)PRINTaANDbPRINTaORbPRINTaXORbPRINTNOTaENDSUB
FreeBASIC does not have rotate operators. Shift Right operator performs arithmetic shift if the left value is signed number and logical shift if the left value is unsigned number.
SUBbitwise(aASInteger,bASInteger)DIMuASUIntegerPRINT"a AND b = ";aANDbPRINT"a OR b = ";aORbPRINT"a XOR b = ";aXORbPRINT"NOT a = ";NOTaPRINT"a SHL b = ";aSHLbPRINT"a SHR b (arithmetic) = ";aSHRbu=aPRINT"a SHR b (logical) = ";uSHRbENDSUB
Commodore BASIC V2.0 does not haveXOR,left shift,right shift,right arithmetic shift,left rotate, andright rotate operators. In this implementation theXOR operation is done with an equivalent formula.
10INPUT"A=";A20INPUT"B=";B30PRINT"A AND B ="AANDB:remAND40PRINT"A OR B ="AORB:remOR50PRINT"A XOR B ="(AAND(NOTB))OR((NOTA)ANDB):remXOR60PRINT"NOT A ="NOTA:remNOT
A=? 2B=? 6
A AND B = 2A OR B = 6A XOR B = 4NOT A =-3
100 LET A=10:LET B=12110 PRINT A;"and";B;"=";A AND B120 PRINT A;"band";B;"=";A BAND B130 PRINT A;"or ";B;"=";A OR B140 PRINT A;"bor";B;"=";A BOR B150 PRINT A;"xor";B;"=";XOR(A,B)160 PRINT " not";A;"=";NOT A170 DEF XOR(A,B)=(A BOR B)-(A BAND B)
ZX81 BASIC has no integer type (a major lacuna) and consequently no bitwise operations; but the CPU has them, so we can use a tiny machine code routine to do the actual work and then return to BASIC to print the answers.
This program is a proof of concept, really, and will only work with 8-bit values. In addition, with 1k of RAM there is only space for the first of the shifts/rotates; the others could be implemented along exactly the same lines.
The disassembly of the Z80 code would be:
org 40843a 83 40 ld a, (4083)47 ld b, a3a 82 40 ld a, (4082)a0 and b00 nop ; negate and shift instructions take 2 bytes06 00 ld b, 04f ld c, a ; value in BC reg pair is returned to BASICc9 ret
We then usePOKE statements to replace theand instruction with each successive operation we want to perform.
Note that the left shift instruction shifts by one bit at a time, so we need a loop. The present program has the loop written in BASIC, because it seemed sensible to use BASIC for anything we could use it for and only drop into machine code when there was no alternative; it would of course be faster to do the whole thing in machine code.
Finally, observe that the first line reserves 15 bytes for our machine code routine by hiding them in a comment.
10REMABCDEFGHIJKLMNO20INPUTA30INPUTB40POKE16514,A50POKE16515,B60LETADDR=1651670LETR$="3A8340473A8240A00006004FC9"80POKEADDR,CODER$*16+CODER$(2)-47690LETR$=R$(3TO)100LETADDR=ADDR+1110IFR$<>""THENGOTO80120PRINTA;" AND ";B;" = ";USR16516130POKE16523,176140PRINTA;" OR ";B;" = ";USR16516150POKE16523,168160PRINTA;" XOR ";B;" = ";USR16516170POKE16523,237180POKE16524,68190PRINT"NOT ";A;" = ";USR16516200POKE16523,203210POKE16524,39220FORI=1TOB230POKE16514,USR16516240NEXTI250PRINTA;" << ";B;" = ";PEEK16514
213
21 AND 3 = 121 OR 3 = 2321 XOR 3 = 22NOT 21 = 23521 << 3 = 168
Tiny BASIC has only one data type- the signed 16-bit integer- and no bitwise operations. This code emulates bitwise operations on unsigned 15-bit integers. Since the logic gates AND, NOR, and NXOR are characterised by having exactly two, exactly zero, and exactly one on bit in their inputs, their code is identical except for having a different number of target on bits (line 500 onward). The OR and XOR gates are just NOT NOR and NOT NXOR. The shift and rotate operations are simple divisions and mutiplications by 2, with care taken to avoid overflow, and a carry flag where applicable.
REM VARIABLESREM A = first numberREM B = second numberREM C = resultREM P = current bit positionREM U = number of on bits at position P, or carry flag for rotate opsREM Z = logic gate selection, then target number of on bits10 LET P = 16384 LET F = 0 PRINT "1. A and B" PRINT "2. A or B" PRINT "3. A xor B" PRINT "4. not A" PRINT "5. A shr B" PRINT "6. A shl B" PRINT "7. A ror B" PRINT "8. A rol B" PRINT "Select a bitwise operation." INPUT Z IF Z < 1 THEN GOTO 10 IF Z > 8 THEN GOTO 1011 PRINT "What is A? " INPUT A IF A < 0 THEN GOTO 11 IF Z = 4 THEN GOTO 1512 PRINT "What is B?" INPUT B IF B < 0 THEN GOTO 1215 GOSUB 100 + 10*Z PRINT "The result is ", C,"." END110 LET Z = 2 GOSUB 500 RETURN120 LET Z = 0 GOSUB 500 LET A = C GOSUB 140 RETURN130 LET Z = 1 GOSUB 500 LET A = C GOSUB 140 RETURN140 LET C = 32767 - A RETURN150 IF B = 0 THEN RETURN LET A = A / 2 LET B = B - 1 GOTO 150160 IF B = 0 THEN RETURN IF A > P THEN LET A = A - P LET A = A * 2 LET B = B - 1 GOTO 160170 IF B = 0 THEN RETURN LET U = 0 IF 2*(A/2) <> A THEN LET U = 1 LET A = A / 2 + U*P LET B = B - 1 LET C = A GOTO 170180 IF B = 0 THEN RETURN LET U = 0 IF A >= P THEN LET U = 1 LET A = (A-F*P)*2 + U LET B = B - 1 LET C = A GOTO 180500 LET U = 0 IF B >= P THEN LET U = 1 IF A >= P THEN LET U = U + 1 IF U = Z THEN LET C = C + P IF A >= P THEN LET A = A - P IF B >= P THEN LET B = B - P LET P = P / 2 IF P = 0 THEN RETURN GOTO 500
uBasic/4tH provides the most common bitwise operations as functions. It's not too difficult to provide the arithmetic left and right shift operations.
x = 10y = 2Print "x = "; x Print "y = "; y Print "NOT x = "; NOT(x)Print "x AND y = "; AND(x, y)Print "x OR y = "; OR(x, y)Print "x XOR y = "; XOR(x, y)Print "x SHL y = "; SHL(x, y)Print "x SHR y = "; SHL(x, -y) Print "x ROL y = "; FUNC(_rotl (x, y))Print "x ROR y = "; FUNC(_rotr (x, y))End_rotr Param (2) : Return (OR(SHL(a@, -b@), SHL(a@, Info("wordsize")-b@)))_rotl Param (2) : Return (OR(SHL(a@, b@), SHL(a@, -Info("wordsize")+b@)))x = 10y = 2NOT x = -11x AND y = 2x OR y = 10x XOR y = 8x SHL y = 40x SHR y = 2x ROL y = 40x ROR y = -92233720368547758060 OK, 0:320
# bitwise operators - floating point numbers will be cast to integera = 0b00010001b = 0b11110000print aprint int(a * 2) # shift left (multiply by 2)print a \ 2 # shift right (integer divide by 2)print a | b # bitwise or on two integer valuesprint a & b # bitwise or on two integer values
The SET command with the /A option supports arithmetic and bit operations on signed 8 byte integers.
The SET /? documentation claims it supports logical shift operations, but in reality it performs an arithmetic right shift.
The following script (bitops.bat) not only demonstrates the basic bit operations, it also uses bit operations to convert each integral value into a string of 32 binary digits.
@echo offsetlocalset/a"a=%~1, b=%~2"call:num2bin%a% aStrcall:num2bin%b% bStr::ANDset/a"val=a&b"call:display"%a% AND%b%"%val%%aStr%%bStr%::ORset/a"val=a|b"call:display"%a% OR%b%"%val%%aStr%%bStr%::XORset/a"val=a^b"call:display"%a% XOR%b%"%val%%aStr%%bStr%::NOTset/a"val=~a"call:display"NOT%a%"%val%%aStr%::LEFT SHIFTset/a"val=a<<b"call:display"%a% Left Shift%b%"%val%%aStr%::ARITHMETIC RIGHT SHIFTset/a"val=a>>b"call:display"%a% Arithmetic Right Shift%b%"%val%%aStr%::The remaining operations do not have native support::The implementations use additional operators:: %% = mod:: ! = logical negation where !(zero)=1 and !(non-zero)=0:: * = multiplication:: - = subtraction::LOGICAL RIGHT SHIFT (No native support)set/a"val=(a>>b)&~((0x80000000>>b-1)*!!b)"call:display"%a% Logical Right Shift%b%"%val%%aStr%::ROTATE LEFT (No native support)set/a"val=(a<<b%%32) | (a>>32-b%%32)&~((0x80000000>>31-b%%32)*!!(32-b%%32))"call:display"%a% Rotate Left%b%"%val%%aStr%::ROTATE RIGHT (No native support)set/a"val=(a<<32-b%%32) | (a>>b%%32)&~((0x80000000>>b%%32-1)*!!(b%%32)) "call:display"%a% Rotate Right%b%"%val%%aStr%exit /b:display op result aStr [bStr]echo(echo%~1 =%2echo%3if"%4"neq""echo%4call:num2bin%2exit /b:num2bin IntVal [RtnVar]setlocal enableDelayedExpansionsetn=%~1setrtn=for/l%%bin(0,1,31)do(set/a"d=n&1, n>>=1"setrtn=!d!!rtn!)(endlocal&rem -- return valuesif"%~2"neq""(set%~2=%rtn%)elseecho%rtn%)exit /b
Sample output
>bitops 0x800000FE 7-2147483394 AND 7 = 6100000000000000000000000111111100000000000000000000000000000011100000000000000000000000000000110-2147483394 OR 7 = -2147483393100000000000000000000000111111100000000000000000000000000000011110000000000000000000000011111111-2147483394 XOR 7 = -2147483399100000000000000000000000111111100000000000000000000000000000011110000000000000000000000011111001NOT -2147483394 = 21474833931000000000000000000000001111111001111111111111111111111100000001-2147483394 Left Shift 7 = 325121000000000000000000000001111111000000000000000000111111100000000-2147483394 Arithmetic Right Shift 7 = -167772151000000000000000000000001111111011111111000000000000000000000001-2147483394 Logical Right Shift 7 = 167772171000000000000000000000001111111000000001000000000000000000000001-2147483394 Rotate Left 7 = 325761000000000000000000000001111111000000000000000000111111101000000-2147483394 Rotate Right 7 = -503316471000000000000000000000001111111011111101000000000000000000000001
number1%=&89ABCDEFnumber2%=8PRINT~number1%ANDnumber2%:REM bitwise ANDPRINT~number1%ORnumber2%:REM bitwise ORPRINT~number1%EORnumber2%:REM bitwise exclusive-ORPRINT~NOTnumber1%:REM bitwise NOTPRINT~number1%<<number2%:REM left shiftPRINT~number1%>>>number2%:REM right shift (logical)PRINT~number1%>>number2%:REM right shift (arithmetic)PRINT~(number1%<<number2%)OR(number1%>>>(32-number2%)):REM left rotatePRINT~(number1%>>>number2%)OR(number1%<<(32-number2%)):REM right rotate
#eX~T~T_####>N{` AND `~{~` = `&{Nz1~3JUXe###>{` OR `~{~` = `|{Nz1~5JUXe###>{` XOR `~{~` = `${Nz1~7JUXe###>`NOT `{` = `!{Nz1~9JUXe###>{` << `~{~` = `({Nz1~9PPJUXe###>{` >>> `~{~` = `){` (logical shift right)`N7F+M~1~JUXe###>{` ROL `~{~` = `[{N7F+P~1~JUXe###>{` ROR `~{~` = `]{NN8F+P~1~JUXe###>`Arithmetic shift right is not originally implemented in beeswax.`N q qN`,noitagen yb dezilaer eb nac srebmun evitagen rof RSA ,yllacinhcet tuB`N<##>`logical shift right, and negating the result again:`NN7F++~1~JUXe# #>e# #>~1~[&'pUX{` >> `~{~` = `){` , interpreted as (positive) signed Int64 number (MSB=0), equivalent to >>>`NN; ### >UX`-`!P{M!` >> `~{~` = `!)!`-`M!{` , interpreted as (negative) signed Int64 number (MSB=1)`NN; #>e#Example:
julia>beeswax("Bitops.bswx",0,0.0,Int(20000))i9223653511831486512i489223653511831486512AND48=489223653511831486512OR48=92236535118314865129223653511831486512XOR48=9223653511831486464NOT9223653511831486512=92230905618780651039223653511831486512<<48=135107988821114889223653511831486512>>>48=32769(logicalshiftright)9223653511831486512ROL48=136515406654341129223653511831486512ROR48=3178497Arithmeticshiftrightisnotoriginallyimplementedinbeeswax.Buttechnically,ASRfornegativenumberscanberealizedbynegation,logicalshiftright,andnegatingtheresultagain:-9223090561878065104>>48=-32767,interpretedas(negative)signedInt64number(MSB=1)
The natural number range for beeswax is unsigned Int64, but it is easy to implement signed Int64 by realizing negative numbers by their 2’s complements or interpreting numbers as negative if their MSB is 1, as shown in the example above.
Arithmetic shift right is not originally implemented in beeswax because it does not make sense for unsigned integers, but for negative numbers, it can be realized easily with
A>>B = NOT(NOT(A)>>>B)
as demonstrated above.
In beeswax, rotate left (ROL) and rotate right (ROT) operators are implemented using modulo 64, so rotations by more than 63 bits wrap around:
A ROL B = A<<(B%64)+A>>>(64-B%64)A ROR B = A>>>(B%64)+A<<(64-B%64)
>vMCR>v123456>61g-:|89>&&\481p>88*61p371p>:61g\`!:68*+71g81gp|7>61g2/61p71g1+71pv>v>v>v>v<>^>#A1$^^<B6^<^>^>^>^1C|!`5p18:+1g18$<^9p#p17*93p189p150<>61g71g81gg+71g81gpvD>071g81gpv^<AND>+2\`!#^_>vXOR+2%#^_>vOR+1\`!#^_>vNOT!#^_>vLSHFT0#^_>48*71g3+81gpvRSHFT$48*71g3+81gp#^_>vEENDv#^_>>61g2*61pv@Fv_^#`2:<>71g81gg.48*71g2+81gp79*1-71g2+81g1+pv^<_v#!`2p15:+1g15p18+1g18<^<G
The labelled points (1 to G) are:1. Read in A and B,2. Set the current operating row (R) to 4,3. Set the current bit value (M) to 64,4. Set Current operating column (C) to 3,5. Check if M > A (i.e. bit is 0 or 1),6. Write the bit value into location (R,C),7. A = A - M,8. M = M/2,9. C++,A&B. Storage of corresponding bits,C. Initialise R & C to operation storage (OP) and M to 1,D. Increment OP by M if true,E. M = M*2,F (2 rows below). Print value of OP, increment operation to perform by moving ">" down,G. If doing the NOT, LSHFT or RSHFT (current operation to perform > 3) only read A.
The code requires input be separated by spaces and only works for numbers less than 128, due to form of bit storage and ASCII locations not able to store beyond 127. Overflow will happen if 127 is shifted left due to aforementioned ASCII limit in most Befunge-93 interpreters.
Inputs:
21 3
1 22 23 106 42 10
voidbitwise(inta,intb){printf("a and b: %d\n",a&b);printf("a or b: %d\n",a|b);printf("a xor b: %d\n",a^b);printf("not a: %d\n",~a);printf("a << n: %d\n",a<<b);/* left shift */printf("a >> n: %d\n",a>>b);/* on most platforms: arithmetic right shift *//* convert the signed integer into unsigned, so it will perform logical shift */unsignedintc=a;printf("c >> b: %d\n",c>>b);/* logical right shift *//* there are no rotation operators in C */return0;}
To rotate an integer, you can combine a left shift and a right shift:
/* rotate x to the right by s bits */unsignedintrotr(unsignedintx,unsignedints){return(x>>s)|(x<<32-s);}
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 assembly code:
rotr: movl 4(%esp), %eax ; arg1: x movl 8(%esp), %ecx ; arg2: s rorl %cl, %eax ; right rotate x by s ret
staticvoidbitwise(inta,intb){Console.WriteLine("a and b is {0}",a&b);Console.WriteLine("a or b is {0}",a|b);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);Console.WriteLine("a arshift b is {0}",a>>b);// When the left operand of the >> operator is of a signed integral type,// the operator performs an arithmetic shift rightuintc=(uint)a;Console.WriteLine("c rshift b is {0}",c>>b);// When the left operand of the >> operator is of an unsigned integral type,// the operator performs a logical shift right// there are no rotation operators in C#}
#include<iostream>voidbitwise(inta,intb){std::cout<<"a and b: "<<(a&b)<<'\n';// Note: parentheses are needed because & has lower precedence than <<std::cout<<"a or b: "<<(a|b)<<'\n';std::cout<<"a xor b: "<<(a^b)<<'\n';std::cout<<"not a: "<<~a<<'\n';// Note: the C/C++ shift operators are not guaranteed to work if the shift count (that is, b)// is negative, or is greater or equal to the number of bits in the integer being shifted.std::cout<<"a shl b: "<<(a<<b)<<'\n';// Note: "<<" is used both for output and for left shiftstd::cout<<"a shr b: "<<(a>>b)<<'\n';// typically arithmetic right shift, but not guaranteedunsignedintua=a;std::cout<<"a lsr b: "<<(ua>>b)<<'\n';// logical right shift (guaranteed)// there are no rotation operators in C++, but as of c++20 there is a standard-library rotate function.// The rotate function works for all rotation amounts, but the integer being rotated must always be an// unsigned integer.std::cout<<"a rol b: "<<std::rotl(ua,b)<<'\n';std::cout<<"a ror b: "<<std::rotr(ua,b)<<'\n';}
(bit-andxy)(bit-orxy)(bit-xorxy)(bit-notx)(bit-shift-leftxn)(bit-shift-rightxn);;There is no built-in for rotation.
COBOL 2002 added support for bitwise operations. Shift and rotation operators were added in COBOL 2023. Results are displayed in decimal.
IDENTIFICATIONDIVISION.PROGRAM-ID.bitwise-ops.DATADIVISION.LOCAL-STORAGESECTION.01aPIC 1(32)USAGEBIT.01bPIC 1(32)USAGEBIT.01resultPIC 1(32)USAGEBIT.01result-dispREDEFINESresultPIC S9(9)USAGECOMPUTATIONAL.LINKAGESECTION.01a-intUSAGEBINARY-LONG.01b-intUSAGEBINARY-LONG.PROCEDUREDIVISIONUSINGa-int,b-int.MOVEFUNCTIONBOOLEAN-OF-INTEGER(a-int,32)TOaMOVEFUNCTIONBOOLEAN-OF-INTEGER(b-int,32)TObCOMPUTEresult=aB-ANDbDISPLAY"a and b is "result-dispCOMPUTEresult=aB-ORbDISPLAY"a or b is "result-dispCOMPUTEresult=B-NOTaDISPLAY"Not a is "result-dispCOMPUTEresult=aB-XORbDISPLAY"a exclusive-or b is "result-disp *> More complex operations can be constructed from these.COMPUTEresult=B-NOT(aB-XORb)DISPLAY"Logical equivalence of a and b is "result-dispCOMPUTEresult=(B-NOTa)B-ANDbDISPLAY"Logical implication of a and b is "result-disp *> Shift and rotation operators were only added in COBOL 2023.COMPUTEresult=aB-SHIFT-LbDISPLAY"a shifted left by b is "result-dispCOMPUTEresult=bB-SHIFT-RaDISPLAY"b shifted right by a is "result-dispCOMPUTEresult=aB-SHIFT-LCbDISPLAY"a rotated left by b is "result-dispCOMPUTEresult=bB-SHIFT-RCaDISPLAY"b rotated right by a is "result-dispGOBACK.ENDPROGRAMbitwise-ops.
In older implementations, non-standard extensions were developed as built-in subroutines.
IDENTIFICATIONDIVISION.PROGRAM-ID.mf-bitwise-ops.DATADIVISION.LOCAL-STORAGESECTION.01resultUSAGEBINARY-LONG.78arg-lenVALUELENGTHOFresult.LINKAGESECTION.01aUSAGEBINARY-LONG.01bUSAGEBINARY-LONG.PROCEDUREDIVISIONUSINGa,b.main-line.MOVEbTOresultCALL"CBL_AND"USINGa,result,VALUEarg-lenDISPLAY"a and b is "resultMOVEbTOresultCALL"CBL_OR"USINGa,result,VALUEarg-lenDISPLAY"a or b is "resultMOVEaTOresultCALL"CBL_NOT"USINGresult,VALUEarg-lenDISPLAY"Not a is "resultMOVEbTOresultCALL"CBL_XOR"USINGa,result,VALUEarg-lenDISPLAY"a exclusive-or b is "resultMOVEbTOresultCALL"CBL_EQ"USINGa,result,VALUEarg-lenDISPLAY"Logical equivalence of a and b is "resultMOVEbTOresultCALL"CBL_IMP"USINGa,result,VALUEarg-lenDISPLAY"Logical implication of a and b is "resultGOBACK.ENDPROGRAMmf-bitwise-ops.
CoffeeScript provides sugar for some JavaScript operators, but the bitwise operators are taken directly from JS. See more here:http://coffeescript.org/#operators
f=(a, b) ->p"and",a&bp"or",a|bp"xor",a^bp"not",~ap"<<",a<<bp">>",a>>b# no rotation shifts that I know ofp=(label, n) ->console.loglabel,nf(10,2)
output
> coffee foo.coffee and 2or 10xor 8not -11<< 40>> 2
(defunbitwise(ab)(print(logandab)); AND(print(logiorab)); OR ("ior" = inclusive or)(print(logxorab)); XOR(print(lognota)); NOT(print(ashab)); arithmetic left shift (positive 2nd arg)(print(asha(-b))); arithmetic right shift (negative 2nd arg); no logical shift)
Left and right logical shift may be implemented by the following functions:
(defunshl(xwidthbits)"Compute bitwise left shift of x by 'bits' bits, represented on 'width' bits"(logand(ashxbits)(1-(ash1width))))(defunshr(xwidthbits)"Compute bitwise right shift of x by 'bits' bits, represented on 'width' bits"(logand(ashx(-bits))(1-(ash1width))))
Left and right rotation may be implemented by the following functions:
(defunrotl(xwidthbits)"Compute bitwise left rotation of x by 'bits' bits, represented on 'width' bits"(logior(logand(ashx(modbitswidth))(1-(ash1width)))(logand(ashx(-(-width(modbitswidth))))(1-(ash1width)))))(defunrotr(xwidthbits)"Compute bitwise right rotation of x by 'bits' bits, represented on 'width' bits"(logior(logand(ashx(-(modbitswidth)))(1-(ash1width)))(logand(ashx(-width(modbitswidth)))(1-(ash1width)))))
Trot(T)(inTx,inintshift)purenothrow@nogc{return(x>>>shift)|(x<<(T.sizeof*8-shift));}voidtestBit(ininta,inintb){importstd.stdio;writefln("Input: a = %d, b = %d",a,b);writefln("AND : %8b & %08b = %032b (%4d)",a,b,a&b,a&b);writefln(" OR : %8b | %08b = %032b (%4d)",a,b,a|b,a|b);writefln("XOR : %8b ^ %08b = %032b (%4d)",a,b,a^b,a^b);writefln("LSH : %8b << %08b = %032b (%4d)",a,b,a<<b,a<<b);writefln("RSH : %8b >> %08b = %032b (%4d)",a,b,a>>b,a>>b);writefln("NOT : %8s ~ %08b = %032b (%4d)","",a,~a,~a);writefln("ROT : rot(%8b, %d) = %032b (%4d)",a,b,rot(a,b),rot(a,b));}voidmain(){immutableinta=0b_1111_1111;// bit literal 255immutableintb=0b_0000_0010;// bit literal 2testBit(a,b);}
Input: a = 255, b = 2AND : 11111111 & 00000010 = 00000000000000000000000000000010 ( 2) OR : 11111111 | 00000010 = 00000000000000000000000011111111 ( 255)XOR : 11111111 ^ 00000010 = 00000000000000000000000011111101 ( 253)LSH : 11111111 << 00000010 = 00000000000000000000001111111100 (1020)RSH : 11111111 >> 00000010 = 00000000000000000000000000111111 ( 63)NOT : ~ 11111111 = 11111111111111111111111100000000 (-256)ROT : rot(11111111, 2) = 11000000000000000000000000111111 (-1073741761)
Compilers are usually able to optimize the code pattern of the rot function to one CPU instruction plus loads. The DMD compiler too performs such optimization.
programBitwise;{$APPTYPE CONSOLE}beginWriteln('2 and 3 = ',2and3);Writeln('2 or 3 = ',2or3);Writeln('2 xor 3 = ',2xor3);Writeln('not 2 = ',not2);Writeln('2 shl 3 = ',2shl3);Writeln('2 shr 3 = ',2shr3);// there are no built-in rotation operators in DelphiReadln;end.
DuckDB provides bitwise operations for all the bitwise operators mentioned except for rotations,as illustrated by the first function and table below.
The second table illustrates that the behavior of bitwise `NOT` for integers depends on the type of the argument.
createorreplacefunctiontask(a,b)astable(selecta,b,a&b,a|b,xor(a,b),~a,a<<b,a>>b);fromtask(10,2);
┌───────┬───────┬──────────┬──────────┬────────────┬───────┬───────────┬───────────┐│ 10 │ 2 │ (10 & 2) │ (10 | 2) │ xor(10, 2) │ ~(10) │ (10 << 2) │ (10 >> 2) ││ int32 │ int32 │ int32 │ int32 │ int32 │ int32 │ int32 │ int32 │├───────┼───────┼──────────┼──────────┼────────────┼───────┼───────────┼───────────┤│ 10 │ 2 │ 2 │ 10 │ 8 │ -11 │ 40 │ 2 │└───────┴───────┴──────────┴──────────┴────────────┴───────┴───────────┴───────────┘
select10asv,~(v::BITSTRING),~(v::INT)as"~INT",~(v::BIGINT)as"~BIGINT",~(10::UINTEGER)as"~UINTEGER";
┌───────┬──────────────────────────────────┬───────┬─────────┬────────────────┐│ v │ ~(CAST(v AS BIT)) │ ~INT │ ~BIGINT │ ~UINTEGER ││ int32 │ bit │ int32 │ int64 │ uint32 │├───────┼──────────────────────────────────┼───────┼─────────┼────────────────┤│ 10 │ 11111111111111111111111111110101 │ -11 │ -11 │ 4294967285 ││ │ │ │ │ (4.29 billion) │└───────┴──────────────────────────────────┴───────┴─────────┴────────────────┘
PrintLn('2 and 3 = '+IntToStr(2and3));PrintLn('2 or 3 = '+IntToStr(2or3));PrintLn('2 xor 3 = '+IntToStr(2xor3));PrintLn('not 2 = '+IntToStr(not2));PrintLn('2 shl 3 = '+IntToStr(2shl3));PrintLn('2 shr 3 = '+IntToStr(2shr3));
E provides arbitrary-size integers, so there is no distinct arithmetic and logical shift right. E does not provide bit rotate operations.
def bitwise(a :int, b :int) { println(`Bitwise operations: a AND b: ${a & b} a OR b: ${a | b} a XOR b: ${a ^ b} NOT a: " + ${~a} a left shift b: ${a << b} a right shift b: ${a >> b}`)}# numbers are doubles, bit operations are unsigned, truncate # the fractional part and use 53 integer bitsa = 14b = 3print bitand a bprint bitor a bprint bitxor a bprint bitshift a bprint bitshift a -bprint bitand a bitnot b
21513112112
BitwiseOperations(INTEGERA,INTEGERB):=FUNCTIONBitAND:=A&B;BitOR:=A|B;BitXOR:=A^B;BitNOT:=BNOTA;BitSL:=A<<B;BitSR:=A>>B;DS:=DATASET([{A,B,'Bitwise AND:',BitAND},{A,B,'Bitwise OR:',BitOR},{A,B,'Bitwise XOR',BitXOR},{A,B,'Bitwise NOT A:',BitNOT},{A,B,'ShiftLeft A:',BitSL},{A,B,'ShiftRight A:',BitSR}],{INTEGERAVal,INTEGERBVal,STRING15valuetype,INTEGERval});RETURNDS;END;BitwiseOperations(255,5);//right arithmetic shift, left and right rotate not implemented/* OUTPUT: 2555Bitwise AND: 5 2555Bitwise OR: 255 2555Bitwise XOR 250 2555Bitwise NOT A: -256 2555ShiftLeft A: 8160 2555ShiftRight A: 7*/
moduleBitwiseOps{@InjectConsoleconsole;voidrun(){for((Int64n1,Int64n2):[0=7,1=5,42=2,0x123456789ABCDEF=0xFF]){// <- test datastaticStringhex(Int64n){// <- this is a locally scoped helper function// formats the integer as a hex string, but drops the leading '0' bytesreturnn.toByteArray()[(n.leadingZeroCount/8).minOf(7)..<8].toString();}console.print($|Forvalues{n1}({hex(n1)})and{n2}({hex(n2)}):|{hex(n1)}AND{hex(n2)}={hex(n1&n2)}|{hex(n1)}OR{hex(n2)}={hex(n1|n2)}|{hex(n1)}XOR{hex(n2)}={hex(n1^n2)}|NOT{hex(n1)}={hex(~n1)}|leftshift{hex(n1)}by{n2}={hex(n1<<n2)}|rightshift{hex(n1)}by{n2}={hex(n1>>n2)}|rightarithmeticshift{hex(n1)}by{n2}={hex(n1>>>n2)}|leftrotate{hex(n1)}by{n2}={hex(n1.rotateLeft(n2))}|rightrotate{hex(n1)}by{n2}={hex(n1.rotateRight(n2))}|leftmostbitof{hex(n1)}={hex(n1.leftmostBit)}|rightmostbitof{hex(n1)}={hex(n1.rightmostBit)}|leadingzerocountof{hex(n1)}={n1.leadingZeroCount}|trailingzerocountof{hex(n1)}={n1.trailingZeroCount}|bitcount(aka"population")of{hex(n1)}={n1.bitCount}|reversedbitsof{hex(n1)}={hex(n1.reverseBits())}|reversebytesof{hex(n1)}={hex(n1.reverseBytes())}|);}}}
Results in (extracted for just one of the test values):
For values 1 (0x01) and 5 (0x05): 0x01 AND 0x05 = 0x01 0x01 OR 0x05 = 0x05 0x01 XOR 0x05 = 0x04 NOT 0x01 = 0xFFFFFFFFFFFFFFFE left shift 0x01 by 5 = 0x20 right shift 0x01 by 5 = 0x00 right arithmetic shift 0x01 by 5 = 0x00 left rotate 0x01 by 5 = 0x20 right rotate 0x01 by 5 = 0x0800000000000000 leftmost bit of 0x01 = 0x01 rightmost bit of 0x01 = 0x01 leading zero count of 0x01 = 63 trailing zero count of 0x01 = 0 bit count (aka "population") of 0x01 = 1 reversed bits of 0x01 = 0x8000000000000000 reverse bytes of 0x01 = 0x0100000000000000
ELENA 6.x :
import extensions;extension testOp{ bitwiseTest(y) { Console.printLine(self," and ",y," = ",self.band(y)); Console.printLine(self," or ",y," = ",self.bor(y)); Console.printLine(self," xor ",y," = ",self.bxor(y)); Console.printLine("not ",self," = ",self.BInverted); Console.printLine(self," shr ",y," = ",self.shiftRight(y)); Console.printLine(self," shl ",y," = ",self.shiftLeft(y)); }}public program(){ Console.loadLineTo(new Integer()).bitwiseTest(Console.loadLineTo(new Integer()))}255 and 2 = 2255 or 2 = 255255 xor 2 = 253not 255 = -256255 shr 2 = 63255 shl 2 = 1020
defmoduleBitwise_operationdouseBitwisedeftest(a\\255,b\\170,c\\2)doIO.puts"Bitwise function:"IO.puts"band(#{a},#{b}) =#{band(a,b)}"IO.puts"bor(#{a},#{b}) =#{bor(a,b)}"IO.puts"bxor(#{a},#{b}) =#{bxor(a,b)}"IO.puts"bnot(#{a}) =#{bnot(a)}"IO.puts"bsl(#{a},#{c}) =#{bsl(a,c)}"IO.puts"bsr(#{a},#{c}) =#{bsr(a,c)}"IO.puts"\nBitwise as operator:"IO.puts"#{a} &&&#{b} =#{a&&&b}"IO.puts"#{a} |||#{b} =#{a|||b}"IO.puts"#{a} ^^^#{b} =#{a^^^b}"IO.puts"~~~#{a} =#{~~~a}"IO.puts"#{a} <<<#{c} =#{a<<<c}"IO.puts"#{a} >>>#{c} =#{a>>>c}"endendBitwise_operation.test
Bitwise function:band(255, 170) = 170bor(255, 170) = 255bxor(255, 170) = 85bnot(255) = -256bsl(255, 2) = 1020bsr(255, 2) = 63Bitwise as operator:255 &&& 170 = 170255 ||| 170 = 255255 ^^^ 170 = 85~~~255 = -256255 <<< 2 = 1020255 >>> 2 = 63
All these operations are built-in functions except right arithmetic shift, left rotate, and right rotate.
-module(bitwise_operations).-export([test/0]).test()->A=255,B=170,io:format("~p band~p =~p\n",[A,B,AbandB]),io:format("~p bor~p =~p\n",[A,B,AborB]),io:format("~p bxor~p =~p\n",[A,B,AbxorB]),io:format("not~p =~p\n",[A,bnotA]),io:format("~p bsl~p =~p\n",[A,B,AbslB]),io:format("~p bsr~p =~p\n",[A,B,AbsrB]).
outputs:
255band170=170255bor170=255255bxor170=85not255=-256255bsl170=381627307539845370001346183518875822092557105621893120255bsr170=0
letbitwiseab=printfn"a and b: %d"(a&&&b)printfn"a or b: %d"(a|||b)printfn"a xor b: %d"(a^^^b)printfn"not a: %d"(~~~a)printfn"a shl b: %d"(a<<<b)printfn"a shr b: %d"(a>>>b)// arithmetic shiftprintfn"a shr b: %d"((uint32a)>>>b)// logical shift// No rotation operators.
"a=""b="[writereadlnstring>number]bi@{[bitand"a AND b: "write.][bitor"a OR b: "write.][bitxor"a XOR b: "write.][dropbitnot"NOT a: "write.][absshift"a asl b: "write.][negshift"a asr b: "write.]}2cleave
outputs:
a=255b=5aANDb:5aORb:255aXORb:250NOTa:-256aaslb:8160aasrb:7
Currently rotation and logical shifts are not implemented.
Only AND, OR, and NOT are available.
10 3\$@$@$@$@\ { 3 copies }"a & b = "&."a | b = "|."~a = "%~."":arshift0?do2/loop;\ 2/ is an arithmetic shift right by one bit (2* shifts left one bit):bitwise( a b -- )cr."a ="over.."b ="dup.cr."a and b ="2dupand.cr."a or b ="2dupor.cr."a xor b ="2dupxor.cr."not a ="overinvert.cr."a shl b ="2duplshift.cr."a shr b ="2duprshift.cr."a ashr b ="2duparshift.2drop;
Rotation is not standard, but may be provided in particular Forth implementations, or as an assembly instruction in CODE words.
In ISO Fortran 90 and later the following BIT INTRINSIC functions are defined:
integer::i,j=-1,k=42logical::ai=bit_size(j)! returns the number of bits in the given INTEGER variable! bitwise boolean operations on integersi=iand(k,j)! returns bitwise AND of K and Ji=ior(k,j)! returns bitwise OR of K and Ji=ieor(k,j)! returns bitwise EXCLUSIVE OR of K and Ji=not(j)! returns bitwise NOT of J! single-bit integer/logical operations (bit positions are zero-based)a=btest(i,4)! returns logical .TRUE. if bit position 4 of I is 1, .FALSE. if 0i=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)! multi-bit integer operationsi=ishft(k,j)! returns value of K shifted by J bit positions, with ZERO fill! (right shift if J < 0 and left shift if J > 0).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)i=ishftc(k,j,20)! returns value as before except that ONLY the 20 lowest order! (rightmost) bits are circularly shiftedi=ibits(k,7,8)! extracts 8 contiguous bits from K starting at position 7 and! returns them as the rightmost bits of an otherwise! zero-filled integer. For non-negative K this is! arithmetically equivalent to: MOD((K / 2**7), 2**8)
The following INTRINSIC ELEMENTAL SUBROUTINE is also defined:
callmvbits(k,2,4,j,0)! copy a sequence of 4 bits from k starting at bit 2 into j starting at bit 0
programbits_rosettaimplicit none callbitwise(14,3)containssubroutinebitwise(a,b)implicit noneinteger,intent(in)::a,bcharacter(len=*),parameter::fmt1='(2(a,i10))'character(len=*),parameter::fmt2='(3(a,b32.32),i20)'write(*,fmt1)'input a=',a,' b=',bwrite(*,fmt2)'and : ',a,' & ',b,' = ',iand(a,b),iand(a,b)write(*,fmt2)'or : ',a,' | ',b,' = ',ior(a,b),ior(a,b)write(*,fmt2)'xor : ',a,' ^ ',b,' = ',ieor(a,b),ieor(a,b)write(*,fmt2)'lsh : ',a,' << ',b,' = ',shiftl(a,b),shiftl(a,b)!since F2008, otherwise use ishft(a, abs(b))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))end subroutinebitwiseend programbits_rosetta
Output
Input a= 14 b= 3AND : 00000000000000000000000000001110 & 00000000000000000000000000000011 = 00000000000000000000000000000010 2OR : 00000000000000000000000000001110 | 00000000000000000000000000000011 = 00000000000000000000000000001111 15XOR : 00000000000000000000000000001110 ^ 00000000000000000000000000000011 = 00000000000000000000000000001101 13LSH : 00000000000000000000000000001110 << 00000000000000000000000000000011 = 00000000000000000000000001110000 112RSH : 00000000000000000000000000001110 >> 00000000000000000000000000000011 = 00000000000000000000000000000001 1NOT : 00000000000000000000000000001110 ~ 00000000000000000000000000000011 = 11111111111111111111111111110001 -15ROT : 00000000000000000000000000001110 ~ 00000000000000000000000000000011 = 11000000000000000000000000000001 -1073741823
programBitwise;{$mode objfpc}var// Pascal uses a native int type as a default literal type// Make sure the operants work on an exact type.x:shortint=2;y:ShortInt=3;beginWriteln('2 and 3 = ',xandy);Writeln('2 or 3 = ',xory);Writeln('2 xor 3 = ',xxory);Writeln('not 2 = ',notx);Writeln('2 shl 3 = ',x>>y);Writeln('2 shr 3 = ',x<<y);writeln('2 rol 3 = ',rolbyte(x,y));writeln('2 ror 3 = ',rorbyte(x,y));writeln('2 sar 3 = ',sarshortint(x,y));Readln;end.
' FB 1.05.0 Win64 (Note the (U)Integer type is 64 bits)' FB doesn't have built-in logical shift right or rotation operators' but, as they're not difficult to implement, I've done so below.Functionlsr(xAsConstInteger,yAsConstInteger)AsIntegerDimAsUIntegerz=xReturnzShryEndFunctionFunctionrol(xAsConstInteger,yAsConstUInteger)AsIntegerDimzAsInteger=xDimhighAsIntegerForiAsInteger=1Toyhigh=Bit(z,63)ForjAsInteger=62To0Step-1IfBit(z,j)Thenz=BitSet(z,j+1)Elsez=BitReset(z,j+1)EndIfNextjIfhighThenz=BitSet(z,0)Elsez=BitReset(z,0)EndIfNextiReturnzEndFunctionFunctionror(xAsConstInteger,yAsConstUInteger)AsIntegerDimzAsInteger=xDimlowAsIntegerForiAsInteger=1Toylow=Bit(z,0)ForjAsInteger=1To63IfBit(z,j)Thenz=BitSet(z,j-1)Elsez=BitReset(z,j-1)EndIfNextjIflowThenz=BitSet(z,63)Elsez=BitReset(z,63)EndIfNextiReturnzEndFunctionSubbitwise(xAsInteger,yAsInteger)Print"x = ";xPrint"y = ";yPrint"x AND y = ";xAndyPrint"x OR y = ";xOryPrint"x XOR y = ";xXOryPrint"NOT x = ";NotxPrint"x SHL y = ";xShlyPrint"x SHR y = ";xShryPrint"x LSR y = ";lsr(x,y)Print"x ROL y = ";rol(x,y)Print"x ROR y = ";ror(x,y)EndSubbitwise-15,3PrintPrint"Press any key to quit"Sleep
x = -15y = 3x AND y = 1x OR y = -13x XOR y = -14NOT x = 14x SHL y = -120x SHR y = -2x LSR y = 2305843009213693950x ROL y = -113x ROR y = 4611686018427387902
FB does not have a bitwise symbol for not, but rather uses the "not" expression. It does not support predefined bitwise symbols for rotate left and rotate right, but functions in this demo provide that capability.
window 1, @"Bitwise Operations", (0,0,650,270)def fn rotl( b as long, n as long ) as long = ( ( 2^n * b) mod 256) or (b > 127)def fn rotr( b as long, n as long ) as long = (b >> n mod 32) or ( b << (32-n) mod 32)local fn bitwise( a as long, b as long ) print @"Input: a = "; a; @" b = "; b print print @"AND :", @"a && b = ", bin(a && b), @": "; a && b print @"NAND :", @"a ^& b = ", bin(a ^& b), @": "; a ^& b print @"OR :", @"a || b = ", bin(a || b), @": "; a || b print @"NOR :", @"a ^| b = ", bin(a ^| b), @": "; a ^| b print @"XOR :", @"a ^^ b = ", bin(a ^^ b), @": "; a ^^ b print @"NOT :", @" not a = ", bin( not a), @": "; not a print print @"Left shift :", @"a << b =", bin(a << b), @": "; a << b print @"Right shift :", @"a >> b =", bin(a >> b), @": "; a >> b print print @"Rotate left :", @"fn rotl( a, b ) = ", bin(fn rotl( a, b)), @": "; fn rotl( a, b ) print @"Rotate right :", @"fn rotr( a, b ) = ", bin(fn rotr( a, b )),@": "; fn rotr( a, b )end fnfn bitwise( 255, 2 )HandleEvents
Output:
Input: a = 255 b = 2AND : a && b = 00000000000000000000000000000010 : 2NAND : a ^& b = 00000000000000000000000011111101 : 253OR : a || b = 00000000000000000000000011111111 : 255NOR : a ^| b = 11111111111111111111111111111111 : -1XOR : a ^^ b = 00000000000000000000000011111101 : 253NOT : not a = 11111111111111111111111100000000 : -256Left shift : a << b = 00000000000000000000001111111100 : 1020Right shift : a >> b = 00000000000000000000000000111111 : 63Rotate left : fn rotl( a, b ) = 11111111111111111111111111111111 : -1Rotate right : fn rotr( a, b ) = 11000000000000000000000000111111 : -1073741761
packagemainimport"fmt"funcbitwise(a,bint16){fmt.Printf("a: %016b\n",uint16(a))fmt.Printf("b: %016b\n",uint16(b))// Bitwise logical operationsfmt.Printf("and: %016b\n",uint16(a&b))fmt.Printf("or: %016b\n",uint16(a|b))fmt.Printf("xor: %016b\n",uint16(a^b))fmt.Printf("not: %016b\n",uint16(^a))ifb<0{fmt.Println("Right operand is negative, but all shifts require an unsigned right operand (shift distance).")return}ua:=uint16(a)ub:=uint32(b)// Logical shifts (unsigned left operand)fmt.Printf("shl: %016b\n",uint16(ua<<ub))fmt.Printf("shr: %016b\n",uint16(ua>>ub))// Arithmetic shifts (signed left operand)fmt.Printf("las: %016b\n",uint16(a<<ub))fmt.Printf("ras: %016b\n",uint16(a>>ub))// Rotationsfmt.Printf("rol: %016b\n",uint16(a<<ub|int16(uint16(a)>>(16-ub))))fmt.Printf("ror: %016b\n",uint16(int16(uint16(a)>>ub)|a<<(16-ub)))}funcmain(){vara,bint16=-460,6bitwise(a,b)}
Output:
a: 1111111000110100b: 0000000000000110and: 0000000000000100or: 1111111000110110xor: 1111111000110010not: 0000000111001011shl: 1000110100000000shr: 0000001111111000las: 1000110100000000ras: 1111111111111000rol: 1000110100111111ror: 1101001111111000
Golfscript has no bitshift operators.
{2\?*}:shl;{2\?/}:asr;{1$1$&p 1$1$|p 1$1$^p 1$-1^p 1$1$shl p 1$1$asr p}:bit;10 2 bit;;:n2108-11402
defbitwise={a,b->println"""a & b = ${a} & ${b} = ${a & b}a | b = ${a} | ${b} = ${a | b}a ^ b = ${a} ^ ${b} = ${a ^ b}~ a = ~ ${a} = ${~ a}a << b = ${a} << ${b} = ${a << b}a >> b = ${a} >> ${b} = ${a >> b} arithmetic (sign-preserving) shifta >>> b = ${a} >>> ${b} = ${a >>> b} logical (zero-filling) shift"""}
Program:
bitwise(-15,3)
Output:
a & b = -15 & 3 = 1a | b = -15 | 3 = -13a ^ b = -15 ^ 3 = -14~ a = ~ -15 = 14a << b = -15 << 3 = -120a >> b = -15 >> 3 = -2 arithmetic (sign-preserving) shifta >>> b = -15 >>> 3 = 536870910 logical (zero-filling) shift
Harbour language has a set of core functions, which are fully optimized at compile time, to perform bitwise operations.
PROCEDURE Main(...)local n1 := 42, n2 := 2local aPar := hb_AParams()local nRotif !Empty( aPar )n1 :=Val( aPar[1] )hb_Adel( aPar, 1,.T. )if !Empty( aPar )n2 :=Val( aPar[1] )endifendifclear screen ?"Bitwise operations with two integers" ?"n1 =", hb_ntos(n1) ?"n2 =", hb_ntos(n2) ?"------------------------------------" ?"AND -->", hb_BitAnd( n1, n2 ) ?"OR -->", hb_BitOr( n1, n2 ) ?"XOR -->", hb_BitXor( n1, n2 ) ?"NOT -->", hb_BitNot( n1 ) ?"LSHIFT -->", hb_bitShift( n1, n2 ) ?"RSHIFT -->", hb_bitShift( n1, -n2 ) ?"RarSHIFT -->", hb_bitShift( n1, -n2 ) /* left/right rotation isnot implemented, but we can use inline C-code to do it */ /* rotate n1 to the left by n2 bits */nRot := hb_Inline( n1, n2 ) {HB_UINT x = hb_parni( 1 ), s = hb_parni( 2 );hb_retni( (x << s) | (x >> (-s & 31)) ); } // (x << s) | (x >> (32 - s)); ?"Rotate left -->", nRot /* rotate n1 to the right by n2 bits */nRot := HB_INLINE( n1, n2 ){ HB_UINT x = hb_parni( 1 ), s = hb_parni( 2 );hb_retni( (x >> s) | (x << (32 - s)) ); } ?"Rotate right -->", nRotreturn
Output:
Bitwise operations with two integers n1 = 42 n2 = 2 ------------------------------------ AND --> 2 OR --> 42 XOR --> 40 NOT --> -43 LSHIFT --> 168 RSHIFT --> 10 RarSHIFT --> 10 Rotate left --> 168 Rotate right --> -2147483638
The operations inData.Bits work onInt,Integer, and any of the sized integer and word types.
importData.Bitsbitwise::Int->Int->IO()bitwiseab=mapM_print[a.&.b,a.|.b,a`xor`b,complementa,shiftLab-- left shift,shiftRab-- arithmetic right shift,shiftab-- You can also use the "unified" shift function;-- positive is for left shift, negative is for right shift,shifta(-b),rotateLab-- rotate left,rotateRab-- rotate right,rotateab-- You can also use the "unified" rotate function;-- positive is for left rotate, negative is for right rotate,rotatea(-b)]main::IO()main=bitwise255170
17025585-25600001121501860331520106954752011215018603315201069547520
If you were shifting Words (unsigned integers) instead of Ints, then the shift would be automatically logical shifts:
import Data.Wordprint $ shiftL (-1 :: Word) 1print $ shiftR (-1 :: Word) 1
There is no rotate and no shift support built in to HicEst
i = IAND(k, j)i = IOR( k, j)i = IEOR(k, j)i = NOT( k )
EXPORT BITOPS(a, b)BEGINPRINT(BITAND(a, b));PRINT(BITOR(a, b));PRINT(BITXOR(a, b));PRINT(BITNOT(a));PRINT(BITSL(a, b));PRINT(BITSR(a, b));// HPPPL has no builtin rotates or arithmetic right shift.END;
linkbitint# for int2bitproceduremain()bitdemo(255,2)bitdemo(-15,3)endprocedurebitdemo(i,i2)write()demowrite("i",i)demowrite("i2",i2)demowrite("complement i",icom(i))demowrite("i or i2",ior(i,i2))demowrite("i and i2",iand(i,i2))demowrite("i xor i2",ixor(i,i2))demowrite("i shift "||i2,ishift(i,i2))demowrite("i shift -"||i2,ishift(i,-i2))returnendproceduredemowrite(vs,v)returnwrite(vs,": ",v," = ",int2bit(v),"b")end
Icon/Unicon implements bitwise operations on integers. Because integers can be transparently large integers operations that require fixed sizes don't make sense and aren't defined. These include rotation and logical shifting (shift is arithmetic) . Please note also that 'not' is a reserved word and the negation function is 'icom'
Sample output:
i: 255 = 11111111bi2: 2 = 10bcomplement i: -256 = -100000000bi or i2: 255 = 11111111bi and i2: 2 = 10bi xor i2: 253 = 11111101bi shift 2: 1020 = 1111111100bi shift -2: 63 = 111111bi: -15 = -1111bi2: 3 = 11bcomplement i: 14 = 1110bi or i2: -13 = -1101bi and i2: 1 = 1bi xor i2: -14 = -1110bi shift 3: -120 = -1111000bi shift -3: -2 = -10b
Inform 6 has no xor or rotate operators. It also has no shift operators, although the Z-machine, its usual target architecture, does. These can be accessed with inline assembly, which is done here.
[ bitwise a b temp; print "a and b: ", a & b, "^"; print "a or b: ", a | b, "^"; print "not a: ", ~a, "^"; @art_shift a b -> temp; print "a << b (arithmetic): ", temp, "^"; temp = -b; @art_shift a temp -> temp; print "a >> b (arithmetic): ", temp, "^"; @log_shift a b -> temp; print "a << b (logical): ", temp, "^"; temp = -b; @log_shift a temp -> temp; print "a >> b (logical): ", temp, "^";];
Here are the "bitwise operators":
bAND=:17b.NB. 16+#.0 0 0 1bOR=:23b.NB. 16+#.0 1 1 1bXOR=:22b.NB. 16+#.0 1 1 0b1NOT=:28b.NB. 16+#.1 1 0 0bLshift=:33b.~NB. see http://www.jsoftware.com/help/release/bdot.htmbRshift=:33b.~-bRAshift=:34b.~-bLrot=:32b.~bRrot=:32b.~-
And here is a routine which takes a list of bitwise operators and two numbers and displays a table of results from combining those two numbers with each of the operators:
bitwise=:1 :0:smoutput(((":x),"1' ',.(>u),.' '),"1":y),"1' => ',"1'.X'{~#:xu`:0y)
And here they are in action:
254bAND`bOR`bXOR`b1NOT`bLshift`bRshift`bRAshift`bLrot`bRrotbitwise3254bAND3=>............................X.254bOR3=>......................XXXXXXXX254bXOR3=>......................XXXXXX.X254b1NOT3=>XXXXXXXXXXXXXXXXXXXXXX.......X254bLshift3=>...................XXXXXXX....254bRshift3=>.........................XXXXX254bRAshift3=>.........................XXXXX254bLrot3=>...................XXXXXXX....254bRrot3=>.........................XXXXX
Further test
bXOR/33335555777799998664
publicstaticvoidbitwise(inta,intb){System.out.println("a AND b: "+(a&b));System.out.println("a OR b: "+(a|b));System.out.println("a XOR b: "+(a^b));System.out.println("NOT a: "+~a);System.out.println("a << b: "+(a<<b));// left shiftSystem.out.println("a >> b: "+(a>>b));// arithmetic right shiftSystem.out.println("a >>> b: "+(a>>>b));// logical right shiftSystem.out.println("a rol b: "+Integer.rotateLeft(a,b));//rotate left, Java 1.5+System.out.println("a ror b: "+Integer.rotateRight(a,b));//rotate right, Java 1.5+}
All of the operators may be combined with the= operator to save space. For example, the following lines each do the same thing:
a<<=3;a=a<<3;a*=8;//2 * 2 * 2 = 8a=a*8;
There are no integers in Javascript, but there are still bitwise operators. They will convert their number operands into integers before performing they task. In other languages, these operators are very close to the hardware and very fast. In JavaScript, they are very far from the hardware and very slow and rarely used.
functionbitwise(a,b){alert("a AND b: "+(a&b));alert("a OR b: "+(a|b));alert("a XOR b: "+(a^b));alert("NOT a: "+~a);alert("a << b: "+(a<<b));// left shiftalert("a >> b: "+(a>>b));// arithmetic right shiftalert("a >>> b: "+(a>>>b));// logical right shift}
Works with jq, the C implementation of jq
Works with gojq, the Go implementation of jq
jq has no built-in bitwise operations, but the "bitwise" moduledefinesall those needed for the task at hand except for rotations.Here `rotateLeft` and rotateRight` functions are defined relative to a given width.
The examples are taken from the entry forWren.
include "bitwise" {search: "."}; # adjust as requireddef leftshift($n; $width): [(range(0,$n)| 0), limit($width - $n; bitwise)][:$width] | to_int;# Using a width of $width bits: x << n | x >> ($width-n)def rotateLeft($x; $n; $width): $x | bitwise_or(leftshift($n; $width); rightshift($width-$n));# Using a width of $width bits: x << n | x >> ($width-n)def rotateRight($x; $n; $width): $x | bitwise_or(rightshift($n); leftshift($width-$n; $width) );def task($x; $y): def isInteger: type == "number" and . == round; if ($x|isInteger|not) or ($y|isInteger|not) or $x < 0 or $y < 0 or $x > 4294967295 or $y > 4294967295 then "Operands must be in the range of a 32-bit unsigned integer" | error else " x = \($x)", " y = \($y)", " x & y = \(bitwise_and($x; $y))", " x | y = \(bitwise_or($x; $y))", " x ^ y = \(null | xor(x; $y))", "~x = \(32 | flip($x))", " x << y = \($x | leftshift($y))", " x >> y = \($x | rightshift($y))", " x rl y = \(rotateLeft($x; $y; 32))", " x rr y = \(rotateRight($x; $y; 32))" end;task(10; 2)x = 10 y = 2 x & y = 2 x | y = 10 x ^ y = 8~x = 4294967295 x << y = 40 x >> y = 2 x rl y = 40 x rr y = 2147483650
# Version 5.2@show1&2# AND@show1|2# OR@show1^2# XOR -- for Julia 6.0 the operator is `⊻`@show~1# NOT@show1>>>2# SHIFT RIGHT (LOGICAL)@show1>>2# SHIFT RIGHT (ARITMETIC)@show1<<2# SHIFT LEFT (ARITMETIC/LOGICAL)A=BitArray([true,true,false,false,true])@showAror(A,1)ror(A,2)ror(A,5)# ROTATION RIGHT@showrol(A,1)rol(A,2)rol(A,5)# ROTATION LEFT
1 & 2 = 01 | 2 = 31 ^ 2 = 1~1 = -21 >>> 2 = 01 >> 2 = 01 << 2 = 4A = Bool[true,true,false,false,true]ror(A,1) = Bool[true,true,true,false,false]ror(A,2) = Bool[false,true,true,true,false]ror(A,5) = Bool[true,true,false,false,true]rol(A,1) = Bool[true,false,false,true,true]rol(A,2) = Bool[false,false,true,true,true]rol(A,5) = Bool[true,true,false,false,true]
funmain(){// inferred type of x and y is Int (32-bit signed integer)valx=10valy=2println("x =$x")println("y =$y")println("NOT x =${x.inv()}")println("x AND y =${xandy}")println("x OR y =${xory}")println("x XOR y =${xxory}")// All operations below actually return (x OP (y % 32)) so that a value is never completely shifted outprintln("x SHL y =${xshly}")println("x ASR y =${xshry}")// arithmetic shift right (sign bit filled)println("x LSR y =${xushry}")// logical shift right (zero filled)println("x ROL y =${x.rotateLeft(y)}")println("x ROR y =${x.rotateRight(y)}")}
x = 10y = 2NOT x = -11x AND y = 2x OR y = 10x XOR y = 8x SHL y = 40x ASR y = 2x LSR y = 2x ROL y = 40x ROR y = -2147483646
All these operations are built-in functions except right arithmetic shift, left rotate, and right rotate.
(defunbitwise(ab)(lists:map(lambda(x)(io:format"~p~n"`(,x)))`(,(bandab),(borab),(bxorab),(bnota),(bslab),(bsrab)))'ok)(defundec->bin(x)(integer_to_listx2))(defundescribe(funcarg1arg2result)(io:format"(~s ~s ~s): ~s~n"(listfunc(dec->binarg1)(dec->binarg2)(dec->binresult))))(defunbitwise((ab'binary)(describe"band"ab(bandab))(describe"bor"ab(borab))(describe"bxor"ab(bxorab))(describe"bnot"ab(bnota))(describe"bsl"ab(bslab))(describe"bsr"ab(bsrab))))
Example usage:
>(bitwise255170)17025585-2563816273075398453700013461835188758220925571056218931200ok>(bitwise255170'binary)(band1111111110101010):10101010(bor1111111110101010):11111111(bxor1111111110101010):1010101(bnot11111111):-100000000(bsl1111111110101010):1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(bsr1111111110101010):0ok>
Written as functions.
' bitwise operations on byte-sized variablesv =int( 256 *rnd( 1))s = 1print "Shift ="; s; " place."printprint "Number as dec. = "; v; " & as 8-bits byte = ", dec2Bin$( v)print "NOT as dec. = "; bitInvert( v), dec2Bin$( bitInvert( v))print "Shifted left as dec. = "; shiftLeft( v, s), dec2Bin$( shiftLeft( v, s))print "Shifted right as dec. = "; shiftRight( v, s), dec2Bin$( shiftRight( v, s))print "Rotated left as dec. = "; rotateLeft( v, s), dec2Bin$( rotateLeft( v, s))print "Rotated right as dec. = "; rotateRight( v, s), dec2Bin$( rotateRight( v, s))endfunction shiftLeft( b, n) shiftLeft =( b *2^n) and 255end functionfunction shiftRight( b, n) shiftRight =int(b /2^n)end functionfunction rotateLeft( b, n) rotateLeft = (( 2^n *b) mod 256) or ( b >127)end functionfunction rotateRight( b, n) rotateRight = (128*( b and 1)) or int( b /2)end functionfunction bitInvert( b) bitInvert =b xor 255end functionfunction dec2Bin$( num) ' Given an integer decimal 0 <--> 255, returns binary equivalent as a string n =num dec2Bin$ ="" while ( num >0) dec2Bin$ =str$( num mod 2) +dec2Bin$ num =int( num /2) wend dec2Bin$ =right$( "00000000" +dec2Bin$, 8)end function
Lingo has built-in functions for bitwise AND, OR, XOR and NOT:
put bitAND(2,7)put bitOR(2,7)put bitXOR(2,7)put bitNOT(7)
Bit shifting and rotating has to be implemented by custom functions.
put "and:" && (255 bitand 2) & comma into bitopsput " or:" && (255 bitor 2) & comma after bitopsput " xor:" && (255 bitxor 2) & comma after bitopsput " not:" && (bitnot 255) after bitopsput bitops-- Ouputand: 2, or: 255, xor: 253, not: 4294967040
LiveCode does not provide built-in bit-shift operations.
; ModuleID = 'test.o';e means little endian;p: { pointer size : pointer abi : preferred alignment for pointers };i same for integers;v is for vectors;f for floats;a for aggregate types;s for stack objects;n: {size:size:size...}, best integer sizestargetdatalayout="e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32";this was compiled with mingw32; thus it must be linked to an ABI compatible c librarytargettriple="i386-mingw32"@.str=privateconstant[13xi8]c"a and b: %d\0A\00",align1; <[13 x i8]*> [#uses=1]@.str1=privateconstant[12xi8]c"a or b: %d\0A\00",align1; <[12 x i8]*> [#uses=1]@.str2=privateconstant[13xi8]c"a xor b: %d\0A\00",align1; <[13 x i8]*> [#uses=1]@.str3=privateconstant[11xi8]c"not a: %d\0A\00",align1; <[11 x i8]*> [#uses=1]@.str4=privateconstant[12xi8]c"a << n: %d\0A\00",align1; <[12 x i8]*> [#uses=1]@.str5=privateconstant[12xi8]c"a >> n: %d\0A\00",align1; <[12 x i8]*> [#uses=1]@.str6=privateconstant[12xi8]c"c >> b: %d\0A\00",align1; <[12 x i8]*> [#uses=1];A function that will do many bitwise opreations to two integer arguments, %a and %bdefinevoid@bitwise(i32%a,i32%b)nounwind{;entry blockentry:;Register to store (a & b)%0=andi32%b,%a; <i32> [#uses=1];print the results%1=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([13xi8]*@.str,i320,i320),i32%0)nounwind; <i32> [#uses=0];Register to store (a | b)%2=ori32%b,%a; <i32> [#uses=1];print the results%3=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([12xi8]*@.str1,i320,i320),i32%2)nounwind; <i32> [#uses=0];Register to store (a ^ b)%4=xori32%b,%a; <i32> [#uses=1];print the results%5=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([13xi8]*@.str2,i320,i320),i32%4)nounwind; <i32> [#uses=0];Register to store (~a)%not=xori32%a,-1; <i32> [#uses=1];print the results%6=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([11xi8]*@.str3,i320,i320),i32%not)nounwind; <i32> [#uses=0];Register to store (a << b)%7=shli32%a,%b; <i32> [#uses=1];print the results%8=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([12xi8]*@.str4,i320,i320),i32%7)nounwind; <i32> [#uses=0];Register to store (a >> b) (a is signed)%9=ashri32%a,%b; <i32> [#uses=1];print the results%10=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([12xi8]*@.str5,i320,i320),i32%9)nounwind; <i32> [#uses=0];Register to store (c >> b), where c is unsiged (eg. logical right shift)%11=lshri32%a,%b; <i32> [#uses=1];print the results%12=tailcalli32(i8*,...)*@printf(i8*getelementptrinbounds([12xi8]*@.str6,i320,i320),i32%11)nounwind; <i32> [#uses=0];terminator instructionretvoid};Declare external fuctionsdeclarei32@printf(i8*nocapture,...)nounwind
to bitwise :a :b (print [a and b:] BitAnd :a :b) (print [a or b:] BitOr :a :b) (print [a xor b:] BitXor :a :b) (print [not a:] BitNot :a) ; shifts are to the left if positive, to the right if negative (print [a lshift b:] LShift :a :b) (print [a lshift -b:] LShift :a minus :b) (print [-a ashift -b:] AShift minus :a minus :b)endbitwise 255 5
The output of this program is:
a and b: 5a or b: 255 a xor b: 250not a: -256a lshift b: 8160a lshift -b: 7-a ashift -b: -8
This example isincorrect. Please fix the code and remove this message.
|
over : 2 pick2dup : over over bitwise : \ " A=" ,t over ,h sp " B=" ,t dup ,h nl \ " A and B=" ,t 2dup & ,h nl \ " A or B=" ,t 2dup | ,h nl \ " A xor B=" ,t over ^ ,h nl \ " not A=" ,t ~ ,h nl \ a \ 7 bitwise # hex literals
LuaBitOp implements bitwise functionality for Lua:
localbit=require"bit"localvb={0,1,-1,2,-2,0x12345678,0x87654321,0x33333333,0x77777777,0x55aa55aa,0xaa55aa55,0x7fffffff,0x80000000,0xffffffff}localfunctioncksum(name,s,r)localz=0fori=1,#sdoz=(z+string.byte(s,i)*i)%2147483629endifz~=rthenerror("bit."..name.." test failed (got "..z..", expected "..r..")",0)endendlocalfunctioncheck_unop(name,r)localf=bit[name]locals=""ifpcall(f)orpcall(f,"z")orpcall(f,true)thenerror("bit."..name.." fails to detect argument errors",0)endfor_,xinipairs(vb)dos=s..","..tostring(f(x))endcksum(name,s,r)endlocalfunctioncheck_binop(name,r)localf=bit[name]locals=""ifpcall(f)orpcall(f,"z")orpcall(f,true)thenerror("bit."..name.." fails to detect argument errors",0)endfor_,xinipairs(vb)dofor_,yinipairs(vb)dos=s..","..tostring(f(x,y))endendcksum(name,s,r)endlocalfunctioncheck_binop_range(name,r,yb,ye)localf=bit[name]locals=""ifpcall(f)orpcall(f,"z")orpcall(f,true)orpcall(f,1,true)thenerror("bit."..name.." fails to detect argument errors",0)endfor_,xinipairs(vb)dofory=yb,yedos=s..","..tostring(f(x,y))endendcksum(name,s,r)endlocalfunctioncheck_shift(name,r)check_binop_range(name,r,0,31)end-- Minimal sanity checks.assert(0x7fffffff==2147483647,"broken hex literals")assert(0xffffffff==-1or0xffffffff==2^32-1,"broken hex literals")assert(tostring(-1)=="-1","broken tostring()")assert(tostring(0xffffffff)=="-1"ortostring(0xffffffff)=="4294967295","broken tostring()")-- Basic argument processing.assert(bit.tobit(1)==1)assert(bit.band(1)==1)assert(bit.bxor(1,2)==3)assert(bit.bor(1,2,4,8,16,32,64,128)==255)
TheRiscLua dialect, forRISC OS, has32-bit integers as the default number type. It provides binary operations& (and), | (or), ^^ (xor), << (logical shift left), >> (logical shift right)and a unary operation ~ (negate).
As of Lua 5.3 most of the required operations are built-in, and those still missing could be derived from them:
a=0xAA55AA55b=0x4print(string.format("%8X and %8X = %16X",a,b,a&b))print(string.format("%8X or %8X = %16X",a,b,a|b))print(string.format("%8X xor %8X = %16X",a,b,a~b))print(string.format("%8s not %8X = %16X","",a,~a))print(string.format("%8X shl %8X = %16X",a,b,a<<b))print(string.format("%8X shr %8X = %16X",a,b,a>>b))-- not built-in, 32-bit substitutes provided:localfunctionsar(x,n)return(x>>n)|(x&0x80000000==0and0or(0xffffffff<<(32-n))&0xffffffff)endlocalfunctionrol(x,n)return((x<<n)&0xffffffff)|(x>>(32-n))endlocalfunctionror(x,n)return(x>>n)|((x<<(32-n))&0xffffffff)endprint(string.format("%8X sar %8X = %16X",a,b,sar(a,b)))print(string.format("%8X rol %8X = %16X",a,b,rol(a,b)))print(string.format("%8X ror %8X = %16X",a,b,ror(a,b)))
AA55AA55 and 4 = 4AA55AA55 or 4 = AA55AA55AA55AA55 xor 4 = AA55AA51 not AA55AA55 = FFFFFFFF55AA55AAAA55AA55 shl 4 = AA55AA550AA55AA55 shr 4 = AA55AA5AA55AA55 sar 4 = FAA55AA5AA55AA55 rol 4 = A55AA55AAA55AA55 ror 4 = 5AA55AA5
binary ops return currency type and internal works with 32bit binary values.
modulebinary_ops{selectcaserandom(1,6)case1Doublex=10,y=2case2Decimalx=10,y=2case3Integerx=10,y=2case4Longx=10,y=2case5' byte from 0 to 255 (unsigned)Bytex=10,y=2caseelseLongLongx=10,y=2endselectprinttype$(x)//x&yvaluesfrom0to4294967295printbinary.not(x)=4294967285,sint(binary.not(x))=-11printbinary.and(x,y)=2printbinary.or(x,y)=10//yvalues-31to31printbinary.xor(x,y)=8printbinary.shift(x,y)=40printbinary.shift(x,-y)=2printbinary.rotate(x,y)=40printbinary.rotate(x,-y)=2147483650,sint(binary.rotate(x,-y))=-2147483646//Binary.NegreturnUnsignedfromsignedvalues:-2147483648(0x8000_0000&)to2147483647(0x7FFF_FFFF&)//values>2147483647return2147483648//values<-2147483648return2147483647//0xFFFF_ABCD&(signedvalue),0xFFFF_ABCDunsingedvaluesamebitsprint0xFFFF_ABCD&=-21555,0xFFFF_ABCD=4294945741,sint(0xFFFF_ABCD)=-21555printBinary.Neg(0xFFFF_ABCD&)=21554,Binary.Not(0xFFFF_ABCD)=21554printsint(Binary.Neg(0xFFFF_ABCD&)+uint(0xFFFF_ABCD&))=sint(Binary.Neg(0))//signed0xFFFF_ABCD&hassamebitsasunsigned0xFFFF_ABCD,//buthavedifferentvalueasusedincalculationsprintBinary.Neg(0xFFFF_ABCD&)=Binary.Not(0xFFFF_ABCD),0xFFFF_ABCD&<>0xFFFF_ABCDprintBinary.Neg(0x0FFF_ABCD&)=Binary.Not(0x0FFF_ABCD),0xFFFF_ABCD&<>0xFFFF_ABCD//Add(modulo32),xunsignedandaddanegatesigned(convertedtounsigned)printbinary.add(x,binary.neg(y),1)=8' 10 - 2 =12printbinary.add(x,binary.neg(-y),1)=12' 10 - - 2 = 12printsint(binary.neg(x))=-11,binary.neg(x)=binary.not(x)}binary_ops
with(Bits):bit:=proc(A,B)locala,b,c,d,e,f,g,h,i,x,bitpow;bitpow:=2^B:a:=And(A,B);b:=Not(A);c:=Or(A,B);d:=Xor(A,B);#Left Shifte:=irem(2*A,bitpow);#Right Shiftf:=iquo(A,2);#Left Rotateg:=irem(2*A,bitpow,'x')+x;#Rightarithshifti:=iquo(A,2)+bitpow/2*irem(A,bitpow/2);returna,b,c,d,e,f,g,i;endproc;
Most functions are built-in or can be made really easily:
(*and xor and or*)BitAnd[integer1,integer2]BitXor[integer1,integer2]BitOr[integer1,integer2](*logical not*)BitNot[integer1](*left and right shift*)BitShiftLeft[integer1]BitShiftRight[integer1](*rotate digits left and right*)FromDigits[RotateLeft[IntegerDigits[integer1,2]],2]FromDigits[RotateRight[IntegerDigits[integer1,2]],2](*right arithmetic shift*)FromDigits[Prepend[Most[#],#[[1]]],2]&[IntegerDigits[integer1,2]]
The function BitShiftLeft, BitShiftRight, RotateRight, RotateLeft all take a second argument, which is the displacement, by default it is set to 1. BitAnd, BitXor and BitOr can handle more than 2 arguments:
BitXor[3333,5555,7777,9999]
gives back:
8664Newer versions of MATLAB have even more bitwise operations than those demonstrated here. A complete list of bitwise operations for the newest version of MATLAB can be found atMathWorks
function bitwiseOps(a,b) disp(sprintf('%d and %d = %d', [a b bitand(a,b)])); disp(sprintf('%d or %d = %d', [a b bitor(a,b)])); disp(sprintf('%d xor %d = %d', [a b bitxor(a,b)])); disp(sprintf('%d << %d = %d', [a b bitshift(a,b)])); disp(sprintf('%d >> %d = %d', [a b bitshift(a,-b)])); endOutput:
>> bitwiseOps(255,2)255 and 2 = 2255 or 2 = 255255 xor 2 = 253255 << 2 = 1020255 >> 2 = 63
load(functs)$a: 3661$b: 2541$logor(a, b);/* 4077 */logand(a, b);/* 2125 */logxor(a, b);/* 1952 *//* NOT(x) is simply -x - 1-a - 1;/* -3662 */logor(a, -a - 1);/* -1 */logand(a, -a - 1);/* 0 */
fn bitwise a b =( format "a and b: %\n" (bit.and a b) format "a or b: %\n" (bit.or a b) format "a xor b: %\n" (bit.xor a b) format "not a: %\n" (bit.not a) format "Left shift a: %\n" (bit.shift a b) format "Right shift a: %\n" (bit.shift a -b))bitwise 255 170
MAXScript doesn't have arithmetic shift or rotate operations.
ML/I only supports bitwise AND and OR operations. These are available from version CKD onwards.
MCSKIP "WITH" NL"" Bitwise operations"" assumes macros on input stream 1, terminal on stream 2MCSKIP MT,<>MCINS %.MCDEF SL SPACES NL AS <MCSET T1=%A1.MCSET T2=%A2.a and b = %%T1.&%T2..a or b = %%T1.|%T2..The other operators are not supported.MCSET S10=0>MCSKIP SL WITH *MCSET S1=1*MCSET S10=2
MODULE Bitwise EXPORTS Main;IMPORT IO, Fmt, Word;VAR c: Word.T;PROCEDURE Bitwise(a, b: INTEGER) = BEGIN IO.Put("a AND b: " & Fmt.Int(Word.And(a, b)) & "\n"); IO.Put("a OR b: " & Fmt.Int(Word.Or(a, b)) & "\n"); IO.Put("a XOR b: " & Fmt.Int(Word.Xor(a, b)) & "\n"); IO.Put("NOT a: " & Fmt.Int(Word.Not(a)) & "\n"); c := a; IO.Put("c LeftShift b: " & Fmt.Unsigned(Word.LeftShift(c, b)) & "\n"); IO.Put("c RightShift b: " & Fmt.Unsigned(Word.RightShift(c, b)) & "\n"); IO.Put("c LeftRotate b: " & Fmt.Unsigned(Word.LeftRotate(c, b)) & "\n"); IO.Put("c RightRotate b: " & Fmt.Unsigned(Word.RightRotate(c, b)) & "\n"); END Bitwise;BEGIN Bitwise(255, 5);END Bitwise.Output:
a AND b: 5a OR b: 255a XOR b: 250NOT a: -256c LeftShift b: 1fe0c RightShift b: 7c LeftRotate b: 1fe0c RightRotate b: f8000007
/** <doc> <h2>bitwise operations</h2> <p>Tectonics: <br> nekoc bitwise.neko <br> neko bitwise</p> </doc>*/// Neko is a signed 31 bit integer VM, full 32 bit requires builtinsvar int32_new = $loader.loadprim("std@int32_new", 1);var int32_and = $loader.loadprim("std@int32_and", 2);var int32_or = $loader.loadprim("std@int32_or", 2);var int32_xor = $loader.loadprim("std@int32_xor", 2);var int32_shl = $loader.loadprim("std@int32_shl", 2);var int32_shr = $loader.loadprim("std@int32_shr", 2);var int32_ushr = $loader.loadprim("std@int32_ushr", 2);var int32_complement = $loader.loadprim("std@int32_complement", 1);// Function to show bitwise operations on a,bvar bitwise = function(a, b) { var ia = int32_new(a); var ib = int32_new(b); $print("Neko 32 bit integer library\n"); $print("a AND b: ", a, " ", b, " ", int32_and(ia, ib), "\n"); $print("a OR b: ", a, " ", b, " ", int32_or(ia, ib), "\n"); $print("a XOR b: ", a, " ", b, " ", int32_xor(ia, ib), "\n"); $print("ones complement a: ", a, " ", int32_complement(ia), "\n"); $print("a SHL b: ", a, " ", b, " ", int32_shl(ia, ib), "\n"); $print("a SHR b: ", a, " ", b, " ", int32_shr(ia, ib), "\n"); $print("a USHR b: ", a, " ", b, " ", int32_ushr(ia, ib), "\n"); $print("a ROL b: is not directly supported in Neko Int32\n"); $print("a ROR b: is not directly supported in Neko Int32\n"); $print("\nNormal Neko 31 bit signed integers\n"); a = $int(a); b = $int(b); $print("a AND b: ", a, " ", b, " ", a & b, "\n"); $print("a OR b: ", a, " ", b, " ", a | b, "\n"); $print("a XOR b: ", a, " ", b, " ", a ^ b, "\n"); $print("NOT a: is not directly supported in Neko syntax\n"); $print("a SHL b: ", a, " ", b, " ", a << b, "\n"); $print("a SHR b: ", a, " ", b, " ", a >> b, "\n"); $print("a USHR b: ", a, " ", b, " ", a >>> b, "\n"); $print("a ROL b: is not directly supported in Neko syntax\n"); $print("a ROR b: is not directly supported in Neko syntax\n");}// Pass command line arguments to the demo function// initially as float, to ensure no internal bit truncationvar a = $float($loader.args[0]);var b = $float($loader.args[1]);if a == null a = 0;if b == null b = 0;bitwise(a,b);prompt$ nekoc bitwise.nekoprompt$ neko bitwise 0x7fffffff 2Neko 32 bit integer librarya AND b: 2147483647 2 2a OR b: 2147483647 2 2147483647a XOR b: 2147483647 2 2147483645ones complement a: 2147483647 -2147483648a SHL b: 2147483647 2 -4a SHR b: 2147483647 2 536870911a USHR b: 2147483647 2 536870911a ROL b: is not directly supported in Neko Int32a ROR b: is not directly supported in Neko Int32Normal Neko 31 bit signed integersa AND b: -1 2 2a OR b: -1 2 -1a XOR b: -1 2 -3NOT a: is not directly supported in Neko syntaxa SHL b: -1 2 -4a SHR b: -1 2 -1a USHR b: -1 2 1073741823a ROL b: is not directly supported in Neko syntaxa ROR b: is not directly supported in Neko syntax
def i = 255;def j = 2;WriteLine($"$i and $j is $(i & j)");WriteLine($"$i or $j is $(i | j)");WriteLine($"$i xor $j is $(i ^ j)");WriteLine($"not $i is $(~i)");WriteLine($"$i lshift $j is $(i << j)");WriteLine($"$i arshift $j is $(i >> j)"); // When the left operand of the >> operator is of a signed integral type, // the operator performs an arithmetic shift rightWriteLine($"$(i :> uint) rshift $j is $(c >> j)"); // When the left operand of the >> operator is of an unsigned integral type, // the operator performs a logical shift right// there are no rotation operators in Nemerle, but you could define your own w/ a macro if you really wanted it
proc bitwise[T: SomeInteger](a, b: T) = echo "a and b: " , a and b echo "a or b: ", a or b echo "a xor b: ", a xor b echo "not a: ", not a echo "a << b: ", a shl b echo "a >> b: ", a shr b
All bitwise operations in NSIS are handled by theIntOp instruction.
Function BitwisePush $0Push $1Push $2StrCpy $0 7StrCpy $1 2IntOp $2 $0 & $1DetailPrint "Bitwise AND: $0 & $1 = $2"IntOp $2 $0 | $1DetailPrint "Bitwise OR: $0 | $1 = $2"IntOp $2 $0 ^ $1DetailPrint "Bitwise XOR: $0 ^ $1 = $2"IntOp $2 $0 ~DetailPrint "Bitwise NOT (negate in NSIS docs): ~$0 = $2"DetailPrint "There are no Arithmetic shifts in NSIS"IntOp $2 $0 >> $1 DetailPrint "Right Shift: $0 >> 1 = $2"IntOp $2 $0 << $1DetailPrint "Left Shift: $0 << $1 = $2"DetailPrint "There are no Rotates in NSIS"Pop $2Pop $1Pop $0FunctionEnd
MODULE Bitwise;IMPORT SYSTEM, Out;PROCEDURE Do(a,b: LONGINT);VAR x,y: SET;BEGIN x := SYSTEM.VAL(SET,a);y := SYSTEM.VAL(SET,b); Out.String("a and b :> ");Out.Int(SYSTEM.VAL(LONGINT,x * y),0);Out.Ln; Out.String("a or b :> ");Out.Int(SYSTEM.VAL(LONGINT,x + y),0);Out.Ln; Out.String("a xor b :> ");Out.Int(SYSTEM.VAL(LONGINT,x / y),0);Out.Ln; Out.String("a and ~b:> ");Out.Int(SYSTEM.VAL(LONGINT,x - y),0);Out.Ln; Out.String("~a :> ");Out.Int(SYSTEM.VAL(LONGINT,-x),0);Out.Ln; Out.String("a left shift b :> ");Out.Int(SYSTEM.VAL(LONGINT,SYSTEM.LSH(x,b)),0);Out.Ln; Out.String("a right shift b :> ");Out.Int(SYSTEM.VAL(LONGINT,SYSTEM.LSH(x,-b)),0);Out.Ln; Out.String("a left rotate b :> ");Out.Int(SYSTEM.VAL(LONGINT,SYSTEM.ROT(x,b)),0);Out.Ln; Out.String("a right rotate b :> ");Out.Int(SYSTEM.VAL(LONGINT,SYSTEM.ROT(x,-b)),0);Out.Ln; Out.String("a arithmetic left shift b :> ");Out.Int(SYSTEM.VAL(LONGINT,ASH(a,b)),0);Out.Ln; Out.String("a arithmetic right shift b :> ");Out.Int(SYSTEM.VAL(LONGINT,ASH(a,-b)),0);Out.LnEND Do;BEGIN Do(10,2);END Bitwise.a and b :> 2a or b :> 10a xor b :> 8a and ~b:> 8~a :> -11a left shift b :> 40a right shift b :> 2a left rotate b :> 40a right rotate b :> -2147483646a arithmetic left shift b :> 40a arithmetic right shift b :> 2
use IO;bundle Default { class Test { function : Main(args : String[]) ~ Nil { BitWise(3, 4); } function : BitWise(a : Int, b : Int) ~ Nil { Console->GetInstance()->Print("a and b: ")->PrintLine(a and b); Console->GetInstance()->Print("a or b: ")->PrintLine(a or b); Console->GetInstance()->Print("a xor b: ")->PrintLine(a xor b); # shift left & right are supported by the compiler and VM but not # exposed to end-users; those instructions are used for optimizations } }}let bitwise a b = Printf.printf "a and b: %d\n" (a land b); Printf.printf "a or b: %d\n" (a lor b); Printf.printf "a xor b: %d\n" (a lxor b); Printf.printf "not a: %d\n" (lnot a); Printf.printf "a lsl b: %d\n" (a lsl b); (* left shift *) Printf.printf "a asr b: %d\n" (a asr b); (* arithmetic right shift *) Printf.printf "a lsr b: %d\n" (a lsr b); (* logical right shift *);;
There's no arithmetic shift nor rotation (and the not can be done through a xor)
function bitops(a, b) s = sprintf("%s %%s %s = %%s\n", dec2bin(a), dec2bin(b)); printf(s, "or", dec2bin(bitor(a, b))); printf(s, "and", dec2bin(bitand(a, b))); printf(s, "xor", dec2bin(bitxor(a, b))); printf(s, "left shift", dec2bin(bitshift(a, abs(b)))); printf(s, "right shift", dec2bin(bitshift(a, -abs(b)))); printf("simul not %s = %s", dec2bin(a), dec2bin(bitxor(a, 0xffffffff)));endfunctionbitops(0x1e, 0x3);There is no built-in for not and rotation
: bitwise(a, b) a b bitAnd println a b bitOr println a b bitXor println a bitLeft(b) println a bitRight(b) println ;
/* ooRexx *************************************************************/ Bit Operations work as in Rexx (of course)* Bit operations are performed up to the length of the shorter string.* The rest of the longer string is copied to the result.* ooRexx introduces the possibility to specify a padding character* to be used for expanding the shorter string.* 10.11.2012 Walter Pachl taken over from REXX and extended for ooRexx**********************************************************************/a=21b=347Say ' a :'c2b(a) ' 'c2x(a)Say ' b :'c2b(b) c2x(b)Say 'bitand(a,b) :'c2b(bitand(a,b)) c2x(bitand(a,b))Say 'bitor(a,b) :'c2b(bitor(a,b)) c2x(bitor(a,b))Say 'bitxor(a,b) :'c2b(bitxor(a,b)) c2x(bitxor(a,b))p='11111111'BSay 'ooRexx only:'Say 'a~bitor(b,p):'c2b(a~bitor(b,p)) c2x(a~bitor(b,p))Exitc2b: return x2b(c2x(arg(1)))
Output:
a :0011001000110001 3231 b :001100110011010000110111 333437bitand(a,b) :001100100011000000110111 323037bitor(a,b) :001100110011010100110111 333537bitxor(a,b) :000000010000010100110111 010537ooRexx only:a~bitor(b,p):001100110011010111111111 3335FF
The only bit operators available in OpenEdge are the GET-BITS() and PUT-BITS() functions. These functions can be used to implement all bitwise operators.
Pari does not support bitwise rotations, which have no obvious meaning with arbitrary-precision integers. See alsobitnegimply for another bitwise operator. For shifts, see alsoshiftmul.
bo(a,b)={ print("And: "bitand(a,b)); print("Or: "bitor(a,b)); print("Not: "bitneg(a)); print("Xor: "bitxor(a,b)); print("Left shift: ",a<<b); print("Right shift: ",a>>b);}While Standard Pascal does not have bitwise operations, most Pascal implementations (including Turbo Pascal and Delphi) extend the standard logical operators to also provide bitwise operations:
var a, b: integer;begin a := 10; { binary 1010 } b := 12; { binary 1100 } writeln('a and b = ', a and b); { 8 = 1000 } writeln('a or b = ', a or b); { 14 = 1110 } writeln('a xor b = ', a xor b) { 6 = 0110 }end.begin var (a,b) := ReadInteger2; Println($'not {a} = {not a}'); Println($'{a} and {b} = {a and b}'); Println($'{a} or {b} = {a or b}'); Println($'{a} xor {b} = {a xor b}'); Println($'{a} shl {b} = {a shl b}'); Println($'{a} shr {b} = {a shr b}');end.7 3not 7 = -87 and 3 = 37 or 3 = 77 xor 3 = 47 shl 3 = 567 shr 3 = 0
use integer; sub bitwise :prototype($$) { ($a, $b) = @_; print 'a and b: '. ($a & $b) ."\n"; print 'a or b: '. ($a | $b) ."\n"; print 'a xor b: '. ($a ^ $b) ."\n"; print 'not a: '. (~$a) ."\n"; print 'a >> b: ', $a >> $b, "\n"; # logical right shift use integer; # "use integer" enables bitwise operations to return signed ints print "after use integer:\n"; print 'a << b: ', $a << $b, "\n"; # left shift print 'a >> b: ', $a >> $b, "\n"; # arithmetic right shift}Phix has four builtin bitwise operations (and/or/xor/not)_bits, which each have sequence and unsigned variants. Note careful use of latter (unsigned) routines here, since Phix naturally preserves signs (and common sense) when it can, rather than rudely treat, for instance, +4,294,967,295 as -1, unless explicitly told to do so as it is below. Likewise the builtin shift operators deliver signed and unbounded results, so we'll wrap them here. There are no builtin rotate routines, but easy enough to devise. The distributed copy (1.0.2+) also contains an (older) inline assembly version, which is obviously not JavaScript compatible, but may be significantly faster, for desktop-only applications.
-- demo\rosetta\Bitwise_operations.exwwithjavascript_semanticsenumSHL,SAR,SHR,ROL,RORfunctionbitop(atoma,integerb,integerop)atomresifop=SHLthen-- Note: Phix doesn't quietly discard high bits...res=and_bitsu(a<<b,#FFFF_FFFF)elsifop=SARthen-- Note: Phix doesn't really do "unsigned numbers", -- Should you want to treat 4G-1 as -1 then:ifa>#7FFF_FFFFthena-=#1_0000_0000endifres=and_bitsu(a>>b,#FFFF_FFFF)elsifop=SHRthenres=and_bitsu(a>>b,#FFFF_FFFF)elsifop=ROLthenreturnor_bitsu(a>>32-b,and_bits(a<<b,#FFFF_FFFF))elsifop=RORthenreturnor_bitsu(a>>b,and_bits(a<<32-b,#FFFF_FFFF))else?9/0endifreturnresendfunctionprocedurebitwise(atoma,atomb)printf(1,"and_bits(%b,%b) = %032b\n",{a,b,and_bitsu(a,b)})printf(1," or_bits(%b,%b) = %032b\n",{a,b,or_bitsu(a,b)})printf(1,"xor_bits(%b,%b) = %032b\n",{a,b,xor_bitsu(a,b)})printf(1,"not_bits(%b) = %032b\n",{a,not_bitsu(a)})printf(1," shl(%b,%b) = %032b\n",{a,b,bitop(a,b,SHL)})printf(1," sar(%b,%b) = %032b\n",{a,b,bitop(a,b,SAR)})printf(1," shr(%b,%b) = %032b\n",{a,b,bitop(a,b,SHR)})printf(1," rol(%b,%b) = %032b\n",{a,b,bitop(a,b,ROL)})printf(1," ror(%b,%b) = %032b\n",{a,b,bitop(a,b,ROR)})endprocedurebitwise(0x800000FE,7)
and_bits(10000000000000000000000011111110,111) = 00000000000000000000000000000110 or_bits(10000000000000000000000011111110,111) = 10000000000000000000000011111111xor_bits(10000000000000000000000011111110,111) = 10000000000000000000000011111001not_bits(10000000000000000000000011111110) = 01111111111111111111111100000001 shl(10000000000000000000000011111110,111) = 00000000000000000111111100000000 sar(10000000000000000000000011111110,111) = 11111111000000000000000000000001 shr(10000000000000000000000011111110,111) = 00000001000000000000000000000001 rol(10000000000000000000000011111110,111) = 00000000000000000111111101000000 ror(10000000000000000000000011111110,111) = 11111101000000000000000000000001
6 var a 3 var bdef tab 9 tochar printenddefdef printBits 8 int>bit reverse print nlenddefa print " = " print tab a printBitsb print " = " print tab b printBitstab "------------------------" print nl"AND = " print tab a b bitand printBits"OR = " print tab a b bitor printBits"XOR = " print tab a b bitxor printBits"NOT = " print tab a bitnot printBits
function bitwise($a, $b){ function zerofill($a,$b) { if($a>=0) return $a>>$b; if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1); // this line shifts a 0 into the sign bit for compatibility, replace with "if($b==0) return $a;" if you need $b=0 to mean that nothing happens return ((~$a)>>$b)^(0x7fffffff>>($b-1)); echo '$a AND $b: ' . $a & $b . '\n'; echo '$a OR $b: ' . $a | $b . '\n'; echo '$a XOR $b: ' . $a ^ $b . '\n'; echo 'NOT $a: ' . ~$a . '\n'; echo '$a << $b: ' . $a << $b . '\n'; // left shift echo '$a >> $b: ' . $a >> $b . '\n'; // arithmetic right shift echo 'zerofill($a, $b): ' . zerofill($a, $b) . '\n'; // logical right shift}PicoLisp has no specific word size. Numbers grow to arbitrary length. Therefore,bitwise NOT, logical (non-arithmetic) SHIFTs, and rotate operations do not makesense.
Bitwise AND:
: (& 6 3)-> 2: (& 7 3 1)-> 1
Bitwise AND-Test (tests if all bits in the first argument are set in thefollowing arguments):
: (bit? 1 2)-> NIL: (bit? 6 3)-> NIL: (bit? 6 15 255)-> 6
Bitwise OR:
: (| 1 2)-> 3: (| 1 2 4 8)-> 15
Bitwise XOR:
: (x| 2 7)-> 5: (x| 2 7 1)-> 4
Shift (right with a positive count, left with a negative count):
: (>> 1 8)-> 4: (>> 3 16)-> 2: (>> -3 16)-> 128: (>> -1 -16)-> -32
Rotate operations are not available
void bitwise(int a, int b){ write("a and b: %d\n", a & b); write("a or b: %d\n", a | b); write("a xor b: %d\n", a ^ b); write("not a: %d\n", ~a); write("a << b: 0x%x\n", a << b); write("a >> b: %d\n", a >> b); // ints in Pike do not overflow, if a particular size of the int // is desired then cap it with an AND operation write("a << b & 0xffffffff (32bit cap): 0x%x\n", a << b & 0xffffffff);}void main(){ bitwise(255, 30);}a and b: 30a or b: 255a xor b: 225not a: -256a << b: 0x3fc0000000a >> b: 0a << b & 0xffffffff (32bit cap): 0xc0000000
/* PL/I can perform bit operations on binary integers. */k = iand(i,j);k = ior(i,j);k = inot(i,j);k = ieor(i,j);k = isll(i,n); /* unsigned shifts i left by n places. */k = isrl(i,n); /* unsigned shifts i right by n places. */k = lower2(i, n); /* arithmetic right shift i by n places. */k = raise2(i, n); /* arithmetic left shift i by n places. *//* PL/I can also perform boolean operations on bit strings *//* of any length: */declare (s, t, u) bit (*);u = s & t; /* logical and */u = s | t; /* logical or */u = ^ s; /* logical not */u = s ^ t; /* exclusive or *//* Built-in rotate functions are not available. *//* They can be readily implemented by the user, though: */u = substr(s, length(s), 1) || substr(s, 1, length(s)-1); /* implements rotate right. */u = substr(s, 2) || substr(s, 1, 1); /* implements rotate left. */
Pluto supports the same bitwise operators as Lua 5.3+ though compound versions (x &= y, x |= y etc.) are also supported though not used for this task.
A pecularity of Lua / Pluto is that '~' is used for both bit inversion and exclusive OR operations since '^' is the exponentiation operator.
-- Rotate left and right are not built-in but we use the-- same 32-bit substitutes as in the Lua 5.3+ example.local function rl(x, y) return ((x << y) & 0xffffffff) | (x >> (32 - y)) endlocal function rr(x, y) return (x >> y) | ((x << (32 - y)) & 0xffffffff) endlocal function bitwise(x, y) print($" x = {x}") print($" y = {y}") print($" x & y = {x & y}") print($" x | y = {x | y}") print($" x ~ y = {x ~ y}") print($"~x = {~x}") print($" x << y = {x << y}") print($" x >> y = {x >> y}") print($" x rl y = {rl(x, y)}") print($" x rr y = {rr(x, y)}")endbitwise(10, 2)x = 10 y = 2 x & y = 2 x | y = 10 x ~ y = 8~x = -11 x << y = 40 x >> y = 2 x rl y = 40 x rr y = 2147483650
define bitwise(a, b); printf(a && b, 'a and b = %p\n'); printf(a || b, 'a or b = %p\n'); printf(a ||/& b, 'a xor b = %p\n'); printf(~~ a, 'not a = %p\n'); printf(a << b, 'left shift of a by b = %p\n'); printf(a >> b, 'arithmetic right shift of a by b = %p\n');enddefine;
Conceptually in Pop11 integers have infinite precision, in particular negative numbers conceptually have infinitely many leading 1's in two's complement notation. Hence, logical right shift is not defined. If needed, logical right shift can be simulated by masking high order bits.
Similarly, on infinitely precise numbers rotation is undefined.
Logical right shift and rotations are not supported in PowerShell.
$X -band $Y$X -bor $Y$X -bxor $Y-bnot $X
$X -shl $Y# Arithmetic right shift$X -shr $Y# Requires quite a stretch of the imagination to call this "native" support of right rotate, but it works[System.Security.Cryptography.SHA256Managed].GetMethod('RotateRight', 'NonPublic, Static', $null, @([UInt32], [Int32]), $null).Invoke($null, @([uint32]$X, $Y))Procedure Bitwise(a, b) Debug a & b ; And Debug a | b ;Or Debug a ! b ; XOr Debug ~a ;Not Debug a << b ; shift left Debug a >> b ; arithmetic shift right ; Logical shift right and rotates are not available ; You can of use inline ASM to achieve this: Define Temp ; logical shift right !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !shr edx, cl !mov dword [p.v_Temp], edx Debug Temp ; rotate left !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !rol edx, cl !mov dword [p.v_Temp], edx Debug Temp ; rotate right !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !ror edx, cl !mov dword [p.v_Temp], edx Debug TempEndProcedure
Python has variable length integers. Usually implementations require fixed-width integers. This we get by &-ing values with a mask of all ones of sufficient length. Below we use a combination of a mask and zero-extended fixed-widthbinary output formatting in calculations and result displays.
def bitwise_built_ins(width, a, b): mask = (1 << width) - 1 print(f"""\ AND: 0b{a :0{width}b} & 0b{b :0{width}b} = 0b{(a & b) & mask :0{width}b} OR: 0b{a :0{width}b} | 0b{b :0{width}b} = 0b{(a | b) & mask :0{width}b} XOR: 0b{a :0{width}b} ^ 0b{b :0{width}b} = 0b{(a ^ b) & mask :0{width}b} NOT: ~ 0b{a :0{width}b} = 0b{(~a) & mask :0{width}b} SHIFTS RIGHT: 0b{a :0{width}b} >> 1 = 0b{(a >> 1) & mask :0{width}b} LEFT: 0b{a :0{width}b} << 1 = 0b{(a << 1) & mask :0{width}b} """)def rotr(width, a, n): "Rotate a, n times to the right" if n < 0: return rotl(width, a, -n) elif n == 0: return a else: mask = (1 << width) - 1 a, n = a & mask, n % width return ((a >> n) # top moved down | ((a & ((1 << n) - 1)) # Bottom masked... << (width - n))) # ... then moved up def rotl(width, a, n): "Rotate a, n times to the left" if n < 0: return rotr(width, a, -n) elif n == 0: return a else: mask = (1 << width) - 1 a, n = a & mask, n % width return (((a << n) & mask) # bottom shifted up and masked | (a >> (width - n))) # Top moved down def asr(width, a, n): "Arithmetic shift a, n times to the right. (sign preserving)." mask, top_bit_mask = ((1 << width) - 1), 1 << (width - 1) if n < 0: return (a << -n) & mask elif n == 0: return a elif n >= width: return mask if a & top_bit_mask else 0 else: a = a & mask if a & top_bit_mask: # Sign bit set? signs = (1 << n) - 1 return a >> n | (signs << width - n) else: return a >> n def helper_funcs(width, a): mask, top_bit_mask = ((1 << width) - 1), 1 << (width - 1) aa = a | top_bit_mask # a with top bit set print(f"""\ ROTATIONS RIGHT: rotr({width}, 0b{a :0{width}b}, 1) = 0b{rotr(width, a, 1) :0{width}b} rotr({width}, 0b{a :0{width}b}, 2) = 0b{rotr(width, a, 2) :0{width}b} rotr({width}, 0b{a :0{width}b}, 4) = 0b{rotr(width, a, 4) :0{width}b} LEFT: rotl({width}, 0b{a :0{width}b}, 1) = 0b{rotl(width, a, 1) :0{width}b} rotl({width}, 0b{a :0{width}b}, 2) = 0b{rotl(width, a, 2) :0{width}b} rotl({width}, 0b{a :0{width}b}, 4) = 0b{rotl(width, a, 4) :0{width}b} SIGN-EXTENDING ARITHMETIC SHIFT RIGHT asr({width}, 0b{a :0{width}b}, 1) = 0b{asr(width, a, 1) :0{width}b} asr({width}, 0b{aa :0{width}b}, 1) = 0b{asr(width, aa, 1) :0{width}b} asr({width}, 0b{a :0{width}b}, 2) = 0b{asr(width, a, 2) :0{width}b} asr({width}, 0b{aa :0{width}b}, 2) = 0b{asr(width, aa, 2) :0{width}b} asr({width}, 0b{a :0{width}b}, 4) = 0b{asr(width, a, 4) :0{width}b} asr({width}, 0b{aa :0{width}b}, 4) = 0b{asr(width, aa, 4) :0{width}b} """)if __name__ == '__main__': bitwise_built_ins(8, 27, 125) helper_funcs(8, 27)AND: 0b00011011 & 0b01111101 = 0b00011001 OR: 0b00011011 | 0b01111101 = 0b01111111 XOR: 0b00011011 ^ 0b01111101 = 0b01100110 NOT: ~ 0b00011011 = 0b11100100 SHIFTS RIGHT: 0b00011011 >> 1 = 0b00001101 LEFT: 0b00011011 << 1 = 0b00110110 ROTATIONS RIGHT: rotr(8, 0b00011011, 1) = 0b10001101 rotr(8, 0b00011011, 2) = 0b11000110 rotr(8, 0b00011011, 4) = 0b10110001 LEFT: rotl(8, 0b00011011, 1) = 0b00110110 rotl(8, 0b00011011, 2) = 0b01101100 rotl(8, 0b00011011, 4) = 0b10110001 SIGN-EXTENDING ARITHMETIC SHIFT RIGHT asr(8, 0b00011011, 1) = 0b00001101 asr(8, 0b10011011, 1) = 0b11001101 asr(8, 0b00011011, 2) = 0b00000110 asr(8, 0b10011011, 2) = 0b11100110 asr(8, 0b00011011, 4) = 0b00000001 asr(8, 0b10011011, 4) = 0b11111001
def bitwise(a, b): print 'a and b:', a & b print 'a or b:', a | b print 'a xor b:', a ^ b print 'not a:', ~a print 'a << b:', a << b # left shift print 'a >> b:', a >> b # arithmetic right shift
Python does not have built in rotate or logical right shift operations.
Note: Newer Python versions (circa 2.4?) will automatically promote integers into "long integers" (arbitrary length, bounded by available memory). This can be noticed especially when using left shift operations. When using bitwise operations one usually wants to keep these bounded to specific sizes such as 8, 16, 32 or 64 bit widths. To do these we use the AND operator with specific values (bitmasks). For example:
# 8-bit bounded shift:x = x << n & 0xff# ditto for 16 bit:x = x << n & 0xffff# ... and 32-bit:x = x << n & 0xffffffff# ... and 64-bit:x = x << n & 0xffffffffffffffff
We can easily implement our own rotation functions. For left rotations this is down by ORing the left shifted and masked lower bits against the right shifted upper bits. For right rotations we perform the converse operations, ORing a set of right shifted lower bits against the appropriate number of left shifted upper bits.
def bitstr(n, width=None): """return the binary representation of n as a string and optionally zero-fill (pad) it to a given length """ result = list() while n: result.append(str(n%2)) n = int(n/2) if (width is not None) and len(result) < width: result.extend(['0'] * (width - len(result))) result.reverse() return ''.join(result)def mask(n): """Return a bitmask of length n (suitable for masking against an int to coerce the size to a given length) """ if n >= 0: return 2**n - 1 else: return 0def rol(n, rotations=1, width=8): """Return a given number of bitwise left rotations of an integer n, for a given bit field width. """ rotations %= width if rotations < 1: return n n &= mask(width) ## Should it be an error to truncate here? return ((n << rotations) & mask(width)) | (n >> (width - rotations))def ror(n, rotations=1, width=8): """Return a given number of bitwise right rotations of an integer n, for a given bit field width. """ rotations %= width if rotations < 1: return n n &= mask(width) return (n >> rotations) | ((n << (width - rotations)) & mask(width))
In this example we show a relatively straightforward function for converting integers into strings of bits, and another simplemask() function to create arbitrary lengths of bits against which we perform our masking operations. Also note that the implementation of these functions defaults to single bit rotations of 8-bit bytes. Additional arguments can be used to over-ride these defaults. Any case where the number of rotations modulo the width is zero represents a rotation of all bits back to their starting positions. This implementation should handle any integer number of rotations over bitfields of any valid (positive integer) length.
' no rotations and shift aritmetic are available in QB64' Bitwise operator in Qbasic and QB64'AND (operator) the bit is set when both bits are set.'EQV (operator) the bit is set when both are set or both are not set.'IMP (operator) the bit is set when both are set or both are unset or the second condition bit is set.'OR (operator) the bit is set when either bit is set.'NOT (operator) the bit is set when a bit is not set and not set when a bit is set.'XOR (operator) the bit is set when just one of the bits are set.Print "Qbasic and QB64 operators"Print " Operator 1 vs 1 1 vs 0 0 vs 0"Print "AND", 1 And 1, 1 And 0, 0 And 0Print " OR", 1 Or 1, 1 Or 0, 0 Or 0Print "XOR", 1 Xor 1, 1 Xor 0, 0 Xor 0Print "EQV", 1 Eqv 1, 1 Eqv 0, 0 Eqv 0Print "IMP", 1 Imp 1, 1 Imp 0, 0 Imp 0Print "NOT", Not 1, Not 0, Not -1, Not -2Print "QB64 operators"Dim As _Byte a, b, ca = 1: b = 1: c = 1For i = 1 To 4 Print a, b, c Print _SHL(a, i), _SHL(b, i * 2), _SHL(c, i * 3)Nexta = 16: b = 32: c = 8For i = 1 To 4 Print a, b, c Print _SHR(a, i), _SHR(b, i * 2), _SHR(c, i * 3)Next
Integers in Quackery are bignums, so the bitwise left rotate wordrot64 rotates specifically the least significant 64 bits of an integer. There is no corresponding bitwise right rotate, but it is readily defined fromrot64.
[ [] swap 64 times [ 2 /mod number$ rot join swap ] drop echo$ cr ] is echobin ( n --> ) [ 64 swap - rot64 ] is rrot64 ( n --> n ) [ say "first integer: " over echobin say "second integer: " dup echobin say "bitwise AND: " 2dup & echobin say "bitwise OR: " 2dup | echobin say "bitwise XOR: " 2dup ^ echobin say "bitwise NOT: " over ~ echobin say "bitwise LSHIFT: " 2dup << echobin say "bitwise RSHIFT: " 2dup >> echobin say "bitwise LROTATE: " 2dup rot64 echobin say "bitwise RROTATE: " rrot64 echobin ] is task ( n n --> )hex FFFFF hex F task
first integer: 0000000000000000000000000000000000000000000011111111111111111111second integer: 0000000000000000000000000000000000000000000000000000000000001111bitwise AND: 0000000000000000000000000000000000000000000000000000000000001111bitwise OR: 0000000000000000000000000000000000000000000011111111111111111111bitwise XOR: 0000000000000000000000000000000000000000000011111111111111110000bitwise NOT: 1111111111111111111111111111111111111111111100000000000000000000bitwise LSHIFT: 0000000000000000000000000000011111111111111111111000000000000000bitwise RSHIFT: 0000000000000000000000000000000000000000000000000000000000011111bitwise LROTATE: 0000000000000000000000000000011111111111111111111000000000000000bitwise RROTATE: 1111111111111110000000000000000000000000000000000000000000011111
# Since R 3.0.0, the base package provides bitwise operators, see ?bitwAnda <- 35b <- 42bitwAnd(a, b)bitwOr(a, b)bitwXor(a, b)bitwNot(a)bitwShiftL(a, 2)bitwShiftR(a, 2)
See alsohttps://cran.r-project.org/doc/manuals/r-release/NEWS.3.html.
a <- as.hexmode(35)b <- as.hexmode(42)as.integer(a & b) # 34as.integer(a | b) # 43as.integer(xor(a, b)) # 9
The logical operators in R, namely &, | and !, are designed to work on logical vectors rather than bits. It is possible to convert from integer to logical vector and back to make these work as required, e.g.
intToLogicalBits <- function(intx) as.logical(intToBits(intx))logicalBitsToInt <- function(lb) as.integer(sum((2^(0:31))[lb]))"%AND%" <- function(x, y) { logicalBitsToInt(intToLogicalBits(x) & intToLogicalBits(y))}"%OR%" <- function(x, y) { logicalBitsToInt(intToLogicalBits(x) | intToLogicalBits(y))}35 %AND% 42 # 3435 %OR% 42 # 42library(bitops)bitAnd(35, 42) # 34bitOr(35, 42) # 43bitXor(35, 42) # 9bitFlip(35, bitWidth=8) # 220bitShiftL(35, 1) # 70bitShiftR(35, 1) # 17# Note that no bit rotation is provided in this package
#lang racket(define a 255)(define b 5)(list (bitwise-and a b) (bitwise-ior a b) (bitwise-xor a b) (bitwise-not a) (arithmetic-shift a b) ; left shift (arithmetic-shift a (- b))) ; right shift
Output:
'(5 255 250 -256 8160 7)
(formerly Perl 6)
constant MAXINT = uint.Range.max;constant BITS = MAXINT.base(2).chars;# define rotate ops for the fun of itmulti sub infix:<⥁>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).list.rotate(b).reverse] }multi sub infix:<⥀>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).reverse.list.rotate(b)] }sub int-bits (Int $a, Int $b) { say ''; say_bit "$a", $a; say ''; say_bit "1's complement (not) $a", +^$a; say_bit "2's complement $a", +^$a + 1; say_bit "$a and $b", $a +& $b; say_bit "$a or $b", $a +| $b; say_bit "$a xor $b", $a +^ $b; say_bit "$a unsigned shift right $b", ($a +& MAXINT) +> $b; say_bit "$a signed shift right $b", $a +> $b; say_bit "$a rotate right $b", $a ⥁ $b; say_bit "$a shift left $b", $a +< $b; say_bit "$a rotate left $b", $a ⥀ $b;}int-bits(7,2);int-bits(-65432,31);sub say_bit ($message, $value) { printf("%30s: %{'0' ~ BITS}b\n", $message, $value +& MAXINT);}7: 0000000000000000000000000000000000000000000000000000000000000111 1's complement (not) 7: 1111111111111111111111111111111111111111111111111111111111111000 2's complement 7: 1111111111111111111111111111111111111111111111111111111111111001 7 and 2: 0000000000000000000000000000000000000000000000000000000000000010 7 or 2: 0000000000000000000000000000000000000000000000000000000000000111 7 xor 2: 0000000000000000000000000000000000000000000000000000000000000101 7 unsigned shift right 2: 0000000000000000000000000000000000000000000000000000000000000001 7 signed shift right 2: 0000000000000000000000000000000000000000000000000000000000000001 7 rotate right 2: 1100000000000000000000000000000000000000000000000000000000000001 7 shift left 2: 0000000000000000000000000000000000000000000000000000000000011100 7 rotate left 2: 0000000000000000000000000000000000000000000000000000000000011100 -65432: 1111111111111111111111111111111111111111111111110000000001101000 1's complement (not) -65432: 0000000000000000000000000000000000000000000000001111111110010111 2's complement -65432: 0000000000000000000000000000000000000000000000001111111110011000 -65432 and 31: 0000000000000000000000000000000000000000000000000000000000001000 -65432 or 31: 1111111111111111111111111111111111111111111111110000000001111111 -65432 xor 31: 1111111111111111111111111111111111111111111111110000000001110111-65432 unsigned shift right 31: 0000000000000000000000000000000111111111111111111111111111111111 -65432 signed shift right 31: 1111111111111111111111111111111111111111111111111111111111111111 -65432 rotate right 31: 1111111111111110000000001101000111111111111111111111111111111111 -65432 shift left 31: 1111111111111111100000000011010000000000000000000000000000000000 -65432 rotate left 31: 1111111111111111100000000011010001111111111111111111111111111111
Rebol [title: "Rosetta code: Bitwise operations"file: %Bitwise_operations.r3url: https://rosettacode.org/wiki/Bitwise_operations needs: 3.10.0]do-test: function [code][ res: try code case [ error? res [res: join "error: " res/id] integer? res [res: enbase to-binary res 2] ] printf [-21 " == "] reduce [form code res]]foreach test [ [10] [2] [10 AND 2] [10 & 2] [10 OR 2] [10 | 2] [10 XOR 2] [10 >> 2] [10 << 2] [-65432] [complement -65432] [255] [shift 255 -2] [shift 255 56] [shift/logical 255 56]][ do-test test ]
10 == 0000000000000000000000000000000000000000000000000000000000001010 2 == 0000000000000000000000000000000000000000000000000000000000000010 10 AND 2 == 0000000000000000000000000000000000000000000000000000000000000010 10 & 2 == 0000000000000000000000000000000000000000000000000000000000000010 10 OR 2 == 0000000000000000000000000000000000000000000000000000000000001010 10 | 2 == 0000000000000000000000000000000000000000000000000000000000001010 10 XOR 2 == 0000000000000000000000000000000000000000000000000000000000001000 10 >> 2 == 0000000000000000000000000000000000000000000000000000000000000010 10 << 2 == 0000000000000000000000000000000000000000000000000000000000101000 -65432 == 1111111111111111111111111111111111111111111111110000000001101000 complement -65432 == 0000000000000000000000000000000000000000000000001111111110010111 255 == 0000000000000000000000000000000000000000000000000000000011111111 shift 255 -2 == 0000000000000000000000000000000000000000000000000000000000111111 shift 255 56 == error: overflow shift/logical 255 56 == 1111111100000000000000000000000000000000000000000000000000000000
Red [Source: https://github.com/vazub/rosetta-red]a: 10b: 2print [pad "a =" 10 a newlinepad "b =" 10 b newlinepad "a AND b:" 10 a and b newlinepad "a OR b:" 10 a or b newlinepad "a XOR b:" 10 a xor b newlinepad "NOT a:" 10 complement a newlinepad "a >>> b:" 10 a >>> b newlinepad "a >> b:" 10 a >> b newlinepad "a << b:" 10 a << b newline; there are no circular shift operators in Red]
a = 10 b = 2a AND b: 2a OR b: 10a XOR b: 8NOT a: -11a >>> b: 2a >> b: 2a << b: 40
There is no predefined arithmetic shifts in Retro.
: bitwise ( ab- ) cr over "a = %d\n" puts dup "b = %d\n" puts 2over and "a and b = %d\n" puts 2over or "a or b = %d\n" puts 2over xor "a xor b = %d\n" puts over not "not a = %d\n" puts 2over << "a << b = %d\n" puts 2over >> "a >> b = %d\n" puts 2drop ;
╔═══════════════════════════════════════════════════════════════════════════════════════╗ ║ Since REXX stores numbers (indeed, all values) as characters, it makes no sense to ║ ║ "rotate" a value, since there aren't any boundaries for the value. I.E.: there ║ ║ isn't any 32─bit word "container" or "cell" (for instance) to store an integer. ║ ║ ║ ║ Furthermore, since REXX numbers can be arbitrary precision, the concept of rotating ║ ║ a number has no meaning. ║ ╚═══════════════════════════════════════════════════════════════════════════════════════╝
/*REXX program performs bit─wise operations on integers: & | && ¬ «L »R */numeric digits 1000 /*be able to handle ginormous integers.*/ say center('decimal', 9) center("value", 9) center('bits', 50) say copies('─' , 9) copies("─" , 9) copies('─', 50)a = 21 ; call show a , 'A' /* display A */b = 3 ; call show b , 'B' /* display B */ call show bAnd(a, b) , 'A & B' /* and */ call show bOr(a, b) , 'A | B' /* or */ call show bXor(a, b) , 'A && B' /* xor */ call show bNot(a) , '¬ A' /* not */ call show bShiftL(a, b) , 'A [«B]' /* shift left */ call show bShiftR(a, b) , 'A [»B]' /* shirt right */exit /*stick a fork in it, we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/show: say right( arg(1), 9) center( arg(2), 9) right( d2b( arg(1) ), 50); returnd2b: return x2b( d2x( arg(1) ) ) + 0 /*some REXXes have the D2B BIF. */b2d: return x2d( b2x( arg(1) ) ) /* " " " " B2D " */bNot: return b2d( translate( d2b( arg(1) ), 10, 01) ) +0 /*+0 ≡ normalizes a #.*/bShiftL: return b2d( d2b( arg(1) ) || copies(0, arg(2) ) ) +0 /* " " " " " */bAnd: return c2d( bitand( d2c( arg(1) ), d2c( arg(2) ) ) )bOr: return c2d( bitor( d2c( arg(1) ), d2c( arg(2) ) ) )bXor: return c2d( bitxor( d2c( arg(1) ), d2c( arg(2) ) ) )bShiftR: $=substr(reverse(d2b(arg(1))),arg(2)+1); if $='' then $=0; return b2d(reverse($))decimal value bits───────── ───────── ────────────────────────────────────────────────── 21 A 10101 3 B 11 1 A & B 1 23 A | B 10111 22 A && B 10110 10 ¬ A 1010 168 A [«B] 10101000 2 A [»B] 10
x = 8y = 2see "x & y - Binary AND : " + (x & y) + nl see "x | y - Binary OR : " + (x | y) + nlsee "x ^ y - Binary XOR : " + (x ^ y) +nlsee "~x - Binary Ones Complement : " + (~x) + nlsee "x << y - Binary Left Shift : " + (x << y) + nlsee "x >> y - Binary Right Shift : " + (x >> y) + nl
for Raspberry pi pico 2 see instructions to page risc v
# riscv assembly raspberry pico2 rp2350# program bitwise.s# connexion putty com3/*********************************************//* CONSTANTES *//********************************************//* for this file see risc-v task include a file */.include "../../constantesRiscv.inc"/*******************************************//* INITIALED DATAS *//*******************************************/ .dataszMessStart: .asciz "Program riscv start.\r\n"szCariageReturn: .asciz "\r\n"szMessReg0: .asciz "Register s0:\r\n"szMessReg1: .asciz "Register s1:\r\n"szMessAnd: .asciz "And result:\r\n"szMessOr: .asciz "Or result :\r\n"szMessXor: .asciz "Xor result :\r\n"szMessNot: .asciz "Not result :\r\n"szMessNeg: .asciz "Neg result :\r\n"szMessBset: .asciz "Set single bit result :\r\n"szMessSll: .asciz "Shift left result :\r\n"szMessSrl: .asciz "Shift right result :\r\n"szMessSra: .asciz "Shift right arithmetic result :\r\n"szMessRol: .asciz "Rotation left result :\r\n"szMessRor: .asciz "Rotation right result :\r\n"szMessBclr: .asciz "Clear single bit result :\r\n"szMessBext: .asciz "Extraction single bit result :\r\n"szMessBinv: .asciz "Inversion single bit result :\r\n"szMessBrev: .asciz "Bit-reverse within each byte result :\r\n"szMessClz: .asciz "Count leading zeroes result :\r\n"szMessCtz: .asciz "Count trailing zeroes result :\r\n"szMessCpop: .asciz "Population count result :\r\n"szMessPack: .asciz "Pack two halfwords into one word result :\r\n"szMessPackh: .asciz "Pack two byte into one halfword result :\r\n"szMessZip: .asciz "Zip result :\r\n"szMessUnzip: .asciz "Unzip result :\r\n".align 2/*******************************************/ /* UNINITIALED DATA *//*******************************************/ .bss.align 2sConvArea: .skip 24sConvBinaire: .skip 36/**********************************************//* SECTION CODE *//**********************************************/.text.global mainmain: call stdio_init_all # général init1: # start loop connexion li a0,0 # raz argument register call tud_cdc_n_connected # waiting for USB connection beqz a0,1b # return code = zero ? la a0,szMessStart # message address call writeString # display messagela a0,szMessReg0 # message address call writeString # display messageli s0,0b1100mv a0,s0call displayResult la a0,szMessReg1 # message address call writeString # display messageli s1,0b1001mv a0,s1 call displayResult la a0,szMessAnd # and call writeString # display message andi a0,s0,0b1001 # and immediat value call displayResult and a0,s0,s1 # register and call displayResultandn a0,s0,s1 # register and and not call displayResult la a0,szMessOr # or call writeString # display message ori a0,s0,0b1001 # or immediat value call displayResult or a0,s0,s1 # or register call displayResult orn a0,s0,s1 # or and not register call displayResultorc.b a0,s0 # OR-combine of bits within each byte. Generates a mask of nonzero bytes call displayResult la a0,szMessXor # xor call writeString # display message xori a0,s0,0b1001 # xor immediat value call displayResult xor a0,s0,s1 # xor register call displayResultxnor a0,s0,s1 # Bitwise XOR with inverted operand. Equivalently, bitwise NOT of bitwise XOR call displayResult la a0,szMessNot # not call writeString # display messagenot a0,s0 # notcall displayResultla a0,szMessNeg # negation call writeString # display messageneg a0,s0 # negationcall displayResultla a0,szMessSll # shift left call writeString # display message slli a0,s0,11 # shift left immediat value call displayResultli t0,5 sll a0,s0,t0 # shift left register call displayResult la a0,szMessSrl # shift right call writeString # display message srli a0,s0,1 # shift right immediat value call displayResultli t0,5 srl a0,s0,t0 # shift right register call displayResultla a0,szMessSra # Shift right, arithmetic call writeString # display message srai a0,s0,1 # shift right arithmetic immediat value call displayResultli t0,5li t1,0b10000000000000001100000000000000 sra a0,t1,t0 # shift right arithmetic register call displayResult la a0,szMessRol # rotation left call writeString # display messageli t0,5 rol a0,s0,t0 # rotation left register call displayResult la a0,szMessRor # rotation right call writeString # display message rori a0,s0,10 # rotation right immediat value call displayResultli t0,5 ror a0,s0,t0 # rotation right register call displayResultla a0,szMessBclr # Clear single bit. call writeString # display message bclri a0,s0,3 # Clear single bit. immediat value call displayResultli t0,2 bclr a0,s0,t0 # Clear single bit. register call displayResult la a0,szMessBext # Extraction single bit. call writeString # display message bexti a0,s0,3 # Extraction single bit. immediat value call displayResultli t0,2 bext a0,s0,t0 # Extraction single bit. register call displayResultla a0,szMessBinv # Inversion single bit. call writeString # display message binvi a0,s0,3 # Inversion bit. immediat value call displayResultli t0,2 binv a0,s0,t0 # Inversion single bit. register call displayResultla a0,szMessBset # Set single bit call writeString # display message bseti a0,s0,8 # Set single bit (immediate). call displayResultli t0,17 bset a0,s0,t0 # Set single bit call displayResultla a0,szMessClz # Count leading zeroes (starting from MSB, searching LSB-ward). call writeString # display message clz a0,s0 # call displayResultDla a0,szMessCtz # Count trailing zeroes (starting from LSB, searching MSB-ward). call writeString # display message ctz a0,s0 # call displayResultD la a0,szMessCpop # Population count call writeString # display message cpop a0,s0 # call displayResultD la a0,szMessBrev # Bit-reverse within each byte call writeString # display message brev8 a0,s0 # call displayResultla a0,szMessPack # Pack two halfwords into one word call writeString # display messageli t0,0x1234li t1,0x5678 pack a0,t1,t0 # call displayResultHex la a0,szMessPackh # Pack two halfwords into one word call writeString # display messageli t0,0x12li t1,0x34 packh a0,t1,t0 # call displayResultHexla a0,szMessZip # Interleave upper/lower half of register into odd/even bits of result call writeString # display message zip s2,s0 mv a0,s2# call displayResult la a0,szMessUnzip # Deinterleave odd/even bits of register into upper/lower half of result call writeString # display message unzip a0,s2 # call displayResult call getchar100: # final loop j 100b /**********************************************//* display binary Result *//**********************************************//* a0 value */.equ LGZONECONV, 20displayResult: addi sp, sp, -4 # reserve stack sw ra, 0(sp) la a1,sConvBinaire # conversion result address call conversion2 # binary conversion la a0,sConvBinaire # message address call writeString # display message la a0,szCariageReturn call writeString100: lw ra, 0(sp) addi sp, sp, 4 ret/**********************************************//* display Result décimal *//**********************************************//* a0 value */.equ LGZONECONV, 20displayResultD: addi sp, sp, -4 # reserve stack sw ra, 0(sp) la a1,sConvArea # conversion result address call conversion10 # binary conversion la a0,sConvArea # message address call writeString # display message la a0,szCariageReturn call writeString100: lw ra, 0(sp) addi sp, sp, 4 ret/**********************************************//* display hexadecimal result *//**********************************************//* a0 value */.equ LGZONECONV, 20displayResultHex: addi sp, sp, -4 # reserve stack sw ra, 0(sp) la a1,sConvArea # conversion result address call conversion16 # conversion decimal la a0,sConvArea # message address call writeString # display message la a0,szCariageReturn call writeString100: lw ra, 0(sp) addi sp, sp, 4 ret/************************************//* file include Fonctions *//***********************************//* for this file see risc-v task include a file */.include "../../includeFunctions.s"
Program riscv start.Register s0:00000000 00000000 00000000 00001100Register s1:00000000 00000000 00000000 00001001And result:00000000 00000000 00000000 0000100000000000 00000000 00000000 0000100000000000 00000000 00000000 00000100Or result :00000000 00000000 00000000 0000110100000000 00000000 00000000 0000110111111111 11111111 11111111 1111111000000000 00000000 00000000 11111111Xor result :00000000 00000000 00000000 0000010100000000 00000000 00000000 0000010111111111 11111111 11111111 11111010Not result :11111111 11111111 11111111 11110011Neg result :11111111 11111111 11111111 11110100Shift left result :00000000 00000000 01100000 0000000000000000 00000000 00000001 10000000Shift right result :00000000 00000000 00000000 0000011000000000 00000000 00000000 00000000Shift right arithmetic result :00000000 00000000 00000000 0000011011111100 00000000 00000110 00000000Rotation left result :00000000 00000000 00000001 10000000Rotation right result :00000011 00000000 00000000 0000000001100000 00000000 00000000 00000000Clear single bit result :00000000 00000000 00000000 0000010000000000 00000000 00000000 00001000Extraction single bit result :00000000 00000000 00000000 0000000100000000 00000000 00000000 00000001Inversion single bit result :00000000 00000000 00000000 0000010000000000 00000000 00000000 00001000Set single bit result :00000000 00000000 00000001 0000110000000000 00000010 00000000 00001100Count leading zeroes result :28Count trailing zeroes result :2Population count result :2Bit-reverse within each byte result :00000000 00000000 00000000 00110000Pack two halfwords into one word result :12345678Pack two byte into one halfword result :00001234Zip result :00000000 00000000 00000000 01010000Unzip result :00000000 00000000 00000000 00001100
In RLaB the bitwise operations are available forintegers type of numbers. For the operations below if both argumentsare integers then the result of the operation is an integer as well.
>> x = int(3);>> y = int(1);>> z = x && y; printf("0x%08x\n",z); // logical 'and'0x00000001>> z = x || y; printf("0x%08x\n",z); // logical 'or'0x00000003>> z = !x; printf("0x%08x\n",z); // logical 'not'0xfffffffc>> i2 = int(2);>> z = x * i2; printf("0x%08x\n",z); // left-shift is multiplication by 2 where both arguments are integers0x00000006>> z = x / i2; printf("0x%08x\n",z); // right-shift is division by 2 where both arguments are integers0x00000001input string "First value"set "local1" to "input"input string "Second value"set "local2" to "input". ">>> is an arithmetic shift; >> is a logical shift"[ "a AND b = ('local1' a 'local2')"[ "a OR b = ('local1' o 'local2')"[ "a XOR b = ('local1' x 'local2')"[ "NOT a = (~'local1')"[ "a << b = ('local1' << 'local2')"[ "a >> b = ('local1' >> 'local2')"[ "a >>> b = ('local1' >>> 'local2')"end. "Bitwise rotation is not natively supported"≪ { AND OR XOR NOT SL SR ASR RL RR } → a b ops ≪ {} 1 ops SIZEFOR j a →STR " " +IF j 3 ≤THEN b →STR + " " +END ops j GET →STR 2 OVER SIZE 1 - SUB + " -> " + a j 3 ≤ b IFT ops j GET EVAL →STR + +NEXT≫ ≫ ‘BITOPS’ STO{ "# 355h # 113h AND -> # 111h" "# 355h # 113h OR -> # 357h" "# 355h # 113h XOR -> # 246h" "# 355h NOT -> # FCAAh" "# 355h SL -> # 6AAh" "# 355h SR -> # 1AAh" "# 355h ASR -> # 1AAh" "# 355h RL -> # 6AAh" "# 355h RR -> # 81AAh" }Operations made with a word size set at 16 bits.
def bitwise(a, b) form = "%1$7s:%2$6d %2$016b" puts form % ["a", a] puts form % ["b", b] puts form % ["a and b", a & b] puts form % ["a or b ", a | b] puts form % ["a xor b", a ^ b] puts form % ["not a ", ~a] puts form % ["a << b ", a << b] # left shift puts form % ["a >> b ", a >> b] # arithmetic right shiftendbitwise(14,3)
a: 14 0000000000001110 b: 3 0000000000000011a and b: 2 0000000000000010a or b : 15 0000000000001111a xor b: 13 0000000000001101not a : -15 ..11111111110001a << b : 112 0000000001110000a >> b : 1 0000000000000001
fn main() { let a: u8 = 105; let b: u8 = 91; println!("a = {:0>8b}", a); println!("b = {:0>8b}", b); println!("a | b = {:0>8b}", a | b); println!("a & b = {:0>8b}", a & b); println!("a ^ b = {:0>8b}", a ^ b); println!("!a = {:0>8b}", !a); println!("a << 3 = {:0>8b}", a << 3); println!("a >> 3 = {:0>8b}", a >> 3);}Output:
a = 01101001b = 01011011a | b = 01111011a & b = 01001001a ^ b = 00110010!a = 10010110a << 3 = 01001000a >> 3 = 00001101
/* rotations are not available, but are easy to implement with the other bitwise operators */data _null_; a=105; b=91; c=bxor(a,b); d=band(a,b); e=bor(a,b); f=bnot(a); /* on 32 bits */ g=blshift(a,1); h=brshift(a,1); put _all_;run;
S-BASIC does not have bitwise shift or rotate operators. The test values are taken from the 11l example.
var a, b = integera = 10b = 2print "a ="; a; tab(16); hex$(a)print "b ="; b; tab(16); hex$(b)print "a and b ="; a and b; tab(16); hex$(a and b)print "a or b ="; a or b; tab(16); hex$(a or b)print "a xor b ="; a xor b; tab(16); hex$(a xor b)print "not a ="; not a; tab(16); hex$(not a)end
a = 10 000Ab = 2 0002a and b = 2 0002a or b = 10 000Aa xor b = 688 02CDnot a =-11 FFF5
def bitwise(a: Int, b: Int) { println("a and b: " + (a & b)) println("a or b: " + (a | b)) println("a xor b: " + (a ^ b)) println("not a: " + (~a)) println("a << b: " + (a << b)) // left shift println("a >> b: " + (a >> b)) // arithmetic right shift println("a >>> b: " + (a >>> b)) // unsigned right shift println("a rot b: " + Integer.rotateLeft(a, b)) // Rotate Left println("a rol b: " + Integer.rotateRight(a, b)) // Rotate Right}(import (rnrs arithmetic bitwise (6)))(define (bitwise a b) (display (bitwise-and a b)) (newline) (display (bitwise-ior a b)) (newline) (display (bitwise-xor a b)) (newline) (display (bitwise-not a)) (newline) (display (bitwise-arithmetic-shift-right a b)) (newline))(bitwise 255 5)
Output:
5255250-2567
Note: bitwise operations were also described inSRFI-60, with additional aliases (and previously discussed inSRFI-33 which remained draft).
The typeinteger is intended for arithmetic operations.Besides arithmetic shifts, which are seen as multiplication and division by powers of two, no bitwise operations are supported.The typebin32 is intended for bit-pattern operations.Bin32 has the same internal representation as integer.That way conversions between them don't cause an overhead.Right shifting of bin32 values is done with logical shifts.
$ include "seed7_05.s7i"; include "bin32.s7i";const proc: bitwise (in integer: a, in integer: b) is func begin writeln("a: " <& a radix 2 lpad0 32); writeln("b: " <& b radix 2 lpad0 32); writeln("integer operations:"); writeln("a << b: " <& a << b radix 2 lpad0 32); # left shift writeln("a >> b: " <& a >> b radix 2 lpad0 32); # arithmetic right shift end func;const proc: bitwise (in bin32: a, in bin32: b) is func begin writeln("bin32 operations:"); writeln("a and b: " <& a & b radix 2 lpad0 32); writeln("a or b: " <& a | b radix 2 lpad0 32); writeln("a xor b: " <& a >< b radix 2 lpad0 32); writeln("not a: " <& ~a radix 2 lpad0 32); writeln("a << b: " <& a << ord(b) radix 2 lpad0 32); # left shift writeln("a >> b: " <& a >> ord(b) radix 2 lpad0 32); # logical right shift writeln("a rotL b: " <& rotLeft(a, ord(b)) radix 2 lpad0 32); # Rotate Left writeln("a rolR b: " <& rotRight(a, ord(b)) radix 2 lpad0 32); # Rotate Right end func;const proc: main is func begin bitwise(65076, 6); bitwise(bin32(65076), bin32(6)); end func;a: 00000000000000001111111000110100b: 00000000000000000000000000000110integer operations:a << b: 00000000001111111000110100000000a >> b: 00000000000000000000001111111000bin32 operations:a and b: 00000000000000000000000000000100a or b: 00000000000000001111111000110110a xor b: 00000000000000001111111000110010not a: 11111111111111110000000111001011a << b: 00000000001111111000110100000000a >> b: 00000000000000000000001111111000a rotL b: 00000000001111111000110100000000a rolR b: 11010000000000000000001111111000
func bitwise(a, b) { say ('a and b : ', a & b) say ('a or b : ', a | b) say ('a xor b : ', a ^ b) say ('not a : ', ~a) say ('a << b : ', a << b) # left shift say ('a >> b : ', a >> b) # arithmetic right shift} bitwise(14,3)a and b : 2a or b : 15a xor b : 13not a : -15a << b : 112a >> b : 1
BEGIN COMMENT TO MY KNOWLEDGE SIMULA DOES NOT SUPPORT BITWISE OPERATIONS SO WE MUST WRITE PROCEDURES FOR THE JOB ; INTEGER WORDSIZE; WORDSIZE := 32; BEGIN PROCEDURE TOBITS(N,B); INTEGER N; BOOLEAN ARRAY B; BEGIN INTEGER I,BITN; FOR I := WORDSIZE-1 STEP -1 UNTIL 0 DO BEGIN BITN := MOD(N,2); B(I) := BITN<>0; N := N // 2; END; END TOBITS; INTEGER PROCEDURE FROMBITS(B); BOOLEAN ARRAY B; BEGIN INTEGER I, RESULT; FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO RESULT := 2 * RESULT + (IF B(I) THEN 1 ELSE 0); FROMBITS := RESULT; END FROMBITS; INTEGER PROCEDURE BITOP(A,B,F); INTEGER A,B; PROCEDURE F IS BOOLEAN PROCEDURE F(A,B); BOOLEAN A,B;; BEGIN INTEGER I; BOOLEAN ARRAY BA(0:WORDSIZE-1); BOOLEAN ARRAY BB(0:WORDSIZE-1); TOBITS(A,BA); TOBITS(B,BB); FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BA(I) := F(BA(I),BB(I)); BITOP := FROMBITS(BA); END BITOP; INTEGER PROCEDURE BITUOP(A,F); INTEGER A; PROCEDURE F IS BOOLEAN PROCEDURE F(A); BOOLEAN A;; BEGIN INTEGER I; BOOLEAN ARRAY BA(0:WORDSIZE-1); TOBITS(A,BA); FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BA(I) := F(BA(I)); BITUOP := FROMBITS(BA); END BITUOP; BOOLEAN PROCEDURE OPAND(A,B); BOOLEAN A,B; OPAND := A AND B; INTEGER PROCEDURE BITAND(A,B); INTEGER A,B; BITAND := BITOP(A,B,OPAND); BOOLEAN PROCEDURE OPOR(A,B); BOOLEAN A,B; OPOR := A OR B; INTEGER PROCEDURE BITOR(A,B); INTEGER A,B; BITOR := BITOP(A,B,OPOR); BOOLEAN PROCEDURE OPXOR(A,B); BOOLEAN A,B; OPXOR := (A AND NOT B) OR (NOT A AND B); INTEGER PROCEDURE BITXOR(A,B); INTEGER A,B; BITXOR := BITOP(A,B,OPXOR); BOOLEAN PROCEDURE OPNOT(A); BOOLEAN A; OPNOT := NOT A; INTEGER PROCEDURE BITNOT(A); INTEGER A; BITNOT := BITUOP(A,OPNOT); INTEGER PROCEDURE BITSHL(A,B); INTEGER A,B; BEGIN IF B < 0 THEN A := BITSHR(A,-B) ELSE WHILE B > 0 DO BEGIN A := 2 * A; B := B-1; END; BITSHL := A; END BITSHL; INTEGER PROCEDURE BITSHR(A,B); INTEGER A,B; BEGIN IF B < 0 THEN A := BITSHL(A,-B) ELSE WHILE B > 0 DO BEGIN A := A // 2; B := B-1; END; BITSHR := A; END BITSHR; INTEGER PROCEDURE BITROTR(A,B); INTEGER A,B; BEGIN INTEGER I,J; BOOLEAN ARRAY BA(0:WORDSIZE-1); BOOLEAN ARRAY BB(0:WORDSIZE-1); TOBITS(A,BA); FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BEGIN J := MOD(I + B, WORDSIZE); BB(J) := BA(I); END; BITROTR := FROMBITS(BB); END BITROTR; INTEGER PROCEDURE BITROTL(A,B); INTEGER A,B; BITROTL := BITROTR(A,-B); PROCEDURE BITWISE(A,B); INTEGER A,B; BEGIN OUTTEXT("A AND B : "); OUTINT(BITAND(A,B),0); OUTIMAGE; OUTTEXT("A OR B : "); OUTINT(BITOR (A,B),0); OUTIMAGE; OUTTEXT("A XOR B : "); OUTINT(BITXOR(A,B),0); OUTIMAGE; OUTTEXT("NOT A : "); OUTINT(BITNOT(A), 0); OUTIMAGE; OUTTEXT("A << B : "); OUTINT(BITSHL(A,B),0); OUTIMAGE; ! LEFT SHIFT ; OUTTEXT("A >> B : "); OUTINT(BITSHR(A,B),0); OUTIMAGE; ! ARITHMETIC RIGHT SHIFT ; OUTTEXT("A ROTL B : "); OUTINT(BITROTL(A,B),0); OUTIMAGE; ! ROTATE LEFT ; OUTTEXT("A ROTR B : "); OUTINT(BITROTR(A,B),0); OUTIMAGE; ! ROTATE RIGHT ; END BITWISE; BITWISE(14,3); END;ENDA AND B : 2A OR B : 15A XOR B : 13NOT A : -15A << B : 112A >> B : 1A ROTL B : 112A ROTR B : -1073741823
[ |:a :b | inform: (a bitAnd: b) printString. inform: (a bitOr: b) printString. inform: (a bitXor: b) printString. inform: (a bitNot) printString. inform: (a << b) printString. inform: (a >> b) printString.] applyTo: {8. 12}.Bold text
SinceGNU Smalltalk by default runs without a graphical user interface, I wrote the program in that dialect. The actual methods for bitwise operations (bitAnd:, etc.) are the same in all implementations.
| testBitFunc |testBitFunc := [ :a :b | ('%1 and %2 is %3' % { a. b. (a bitAnd: b) }) displayNl. ('%1 or %2 is %3' % { a. b. (a bitOr: b) }) displayNl. ('%1 xor %2 is %3' % { a. b. (a bitXor: b) }) displayNl. ('not %1 is %2' % { a. (a bitInvert) }) displayNl. ('%1 left shift %2 is %3' % { a. b. (a bitShift: b) }) displayNl. ('%1 right shift %2 is %3' % { a. b. (a bitShift: (b negated)) }) displayNl. ].testBitFunc value: 16r7F value: 4 .in addition to the above,
(a bitClear: b) "mask out bits"(a bitAt: index) "retrieve a bit (bit-index, one-based)"(a setBit: index) "set a bit (bit-index)"(a clearBit: index) "clear a bit (bit-index)"(a invertBit: index) "invert a bit (bit index)"lowBit "find the index of the lowest one-bit; zero if none"highBit "find the index of the highest one-bit; zero if none"bitCount "count the one-bits"
Notice that all of those work on arbitrarily large integers (i.e. 1000 factorial lowBit -> 995).
As a structured script.
#!/usr/local/bin/sparpragma annotate( summary, "bitarith" ) @( description, "Write a routine to perform a bitwise AND, OR, and XOR on" ) @( description, "two integers, a bitwise NOT on the first integer, a left" ) @( description, "shift, right shift, right arithmetic shift, left rotate," ) @( description, "and right rotate. All shifts and rotates should be done on" ) @( description, "the first integer with a shift/rotate amount of the second" ) @( description, "integer." ) @( category, "tutorials" ) @( author, "Ken O. Burtch" ) @( see_also, "http://rosettacode.org/wiki/Bitwise_operations" );pragma license( unrestricted );pragma software_model( shell_script );pragma restriction( no_external_commands );procedure bitarith is A : constant natural := 255; B : constant natural := 170; X : constant natural := 128; N : constant natural := 1;begin put( "A and B = " ) @ (A and B); new_line; put( "A or B = " ) @ (A or B); new_line; put( "A xor B = " ) @ (A xor B); new_line; new_line; put( "A << B = " ) @ ( numerics.shift_left( X, N ) ); new_line; put( "A >> B = " ) @ ( numerics.shift_right( X, N ) ); new_line; put( "A >>> B = " ) @ ( numerics.shift_right_arithmetic( X, N ) ); new_line; put( "A rotl B = " ) @ ( numerics.rotate_left( X, N ) ); new_line; put( "A rotr B = " ) @ ( numerics.rotate_right( X, N ) ); new_line;end bitarith;
For integers, IntInfs provide bitwise operations:
fun bitwise_ints (a, b) = ( print ("a and b: " ^ IntInf.toString (IntInf.andb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("a or b: " ^ IntInf.toString (IntInf.orb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("a xor b: " ^ IntInf.toString (IntInf.xorb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("not a: " ^ IntInf.toString (IntInf.notb (IntInf.fromInt a )) ^ "\n"); print ("a lsl b: " ^ IntInf.toString (IntInf.<< (IntInf.fromInt a, Word.fromInt b )) ^ "\n"); (* left shift *) print ("a asr b: " ^ IntInf.toString (IntInf.~>> (IntInf.fromInt a, Word.fromInt b )) ^ "\n") (* arithmetic right shift *))More shifts are available for words (unsigned ints):
fun bitwise_words (a, b) = ( print ("a and b: " ^ Word.fmt StringCvt.DEC (Word.andb (a, b)) ^ "\n"); print ("a or b: " ^ Word.fmt StringCvt.DEC (Word.orb (a, b)) ^ "\n"); print ("a xor b: " ^ Word.fmt StringCvt.DEC (Word.xorb (a, b)) ^ "\n"); print ("not a: " ^ Word.fmt StringCvt.DEC (Word.notb a ) ^ "\n"); print ("a lsl b: " ^ Word.fmt StringCvt.DEC (Word.<< (a, b) ) ^ "\n"); (* left shift *) print ("a asr b: " ^ Word.fmt StringCvt.DEC (Word.~>> (a, b) ) ^ "\n"); (* arithmetic right shift *) print ("a asr b: " ^ Word.fmt StringCvt.DEC (Word.>> (a, b) ) ^ "\n") (* logical right shift *))Stata does not have bitwise operators as of version 15.1. It's possible to use Mata functionsinbase andfrombase to convert integers to binary strings, and operate on these, but it will be much slower than native operators. William Matsuoka has written functions for thishere.
func bitwise(a: Int, b: Int) { // All bitwise operations (including shifts) // require both operands to be the same type println("a AND b: \(a & b)") println("a OR b: \(a | b)") println("a XOR b: \(a ^ b)") println("NOT a: \(~a)") println("a << b: \(a << b)") // left shift // for right shifts, if the operands are unsigned, Swift performs // a logical shift; if signed, an arithmetic shift. println("a >> b: \(a >> b)") // arithmetic right shift println("a lsr b: \(Int(bitPattern: UInt(bitPattern: a) >> UInt(bitPattern: b)))") // logical right shift}bitwise(-15,3)a AND b: 1a OR b: -13a XOR b: -14NOT a: 14a << b: -120a >> b: -2a lsr b: 2305843009213693950
Verilog, being a hardware description language, had pretty comprehensive support for bit twiddling; though rotation is still a slightly manual operation. Just to be different, I decided to use a couple of 53-bit integers:
program main; initial begin bit [52:0] a,b,c; a = 53'h123476547890fe; b = 53'h06453bdef23ca6; c = a & b; $display("%h & %h = %h", a,b,c); c = a | b; $display("%h | %h = %h", a,b,c); c = a ^ b; $display("%h ^ %h = %h", a,b,c); c = ~ a; $display("~%h = %h", a, c); c = a << 5; $display("%h << 5 = %h", a, c); c = a >> 5; $display("%h >> 5 = %h", a, c); c = { a[53-23:0], a[52-:23] }; $display("%h rotate-left 23 = %h", a, c); c = { a[1:0], a[52:2] }; $display("%h rotate-right 2 = %h", a, c); endendprogramIf we want to do a variable bit rotation, then we need to think in hardware terms, and build a mux structure (this could be a function, but using a module allows it to be parameterized:
module rotate(in, out, shift); parameter BITS = 32; parameter SHIFT_BITS = 5; input [BITS-1:0] in; output [BITS-1:0] out; input [SHIFT_BITS-1:0] shift; always_comb foreach (out[i]) out[i] = in[ (i+shift) % BITS ];endmodule
of course, one could always write the foreach loop inline.
Bytes values are infinitely extended to the left by sign extension when needed. The shift message can be used for all types of shifts, depending on the fill pattern which is infinitely repeated as needed to supply bits for vacated positions.
def a: [x f075 x];def b: [x 81 x];($a and $b) -> '$a; and $b; is $;$#10;' -> !OUT::write($a or $b) -> '$a; or $b; is $;$#10;' -> !OUT::write($a xor $b) -> '$a; xor $b; is $;$#10;' -> !OUT::write$a::inverse -> 'not $a; is $;$#10;' -> !OUT::write$a::shift&{left: 3, fill: [x 00 x]} -> '$a; shifted left 3 bits is $;$#10;' -> !OUT::write$a::shift&{left: -3, fill: [x 00 x]} -> '$a; shifted right 3 bits is $;$#10;' -> !OUT::write$a::shift&{left: -3, fill: $a(0)} -> '$a; arithmetically shifted right 3 bits is $;$#10;' -> !OUT::write$a::shift&{left: 3, fill: $a} -> '$a; rotated left 3 bits is $;$#10;' -> !OUT::write$a::shift&{left: -3, fill: $a} -> '$a; rotated right 3 bits is $;$#10;' -> !OUT::writef075 and 81 is f001f075 or 81 is fff5f075 xor 81 is 0ff4not f075 is 0f8af075 shifted left 3 bits is 83a8f075 shifted right 3 bits is 1e0ef075 arithmetically shifted right 3 bits is fe0ef075 rotated left 3 bits is 83aff075 rotated right 3 bits is be0e
proc bitwise {a b} { puts [format "a and b: %#08x" [expr {$a & $b}]] puts [format "a or b: %#08x" [expr {$a | $b}]] puts [format "a xor b: %#08x" [expr {$a ^ $b}]] puts [format "not a: %#08x" [expr {~$a}]] puts [format "a << b: %#08x" [expr {$a << $b}]] puts [format "a >> b: %#08x" [expr {$a >> $b}]]}There are no built-in operations for arithmetic right shift or for bit rotation. Indeed, rotation precludes the use of arbitrary-width integers and can only be defined with respect to a particular width. However, we can simulate these operations for 32-bit values (requires Tcl 8.5):
proc bitwiseUnsupported {a b} { set bits 0xFFFFFFFF # Force interpretation as a 32-bit unsigned value puts [format "a ArithRightShift b: %#08x" [expr {($a & $bits) >> $b}]] puts [format "a RotateRight b: %#08x" [expr { (($a >> $b) & ($bits >> $b)) | (($a << (32-$b)) & ($bits ^ ($bits >> $b))) }]] puts [format "a RotateLeft b: %#08x" [expr { (($a << $b) & $bits & ($bits << $b)) | (($a >> (32-$b)) & ($bits ^ ($bits << $b))) }]]}While the TI-89 supports arbitrary-size integers, all bitwise arithmetic is performed on the rightmost 32 bits of the integers' two's complement representation.
The right shift operation fills the new leftmost bit with a copy of the old leftmost bit.
bitwise(a,b)Prgm Local show, oldbase Define show(label, x)=Prgm Local r setMode("Base","DEC") string(x) → r setMode("Base","HEX") Disp label & r & " " & string(x) EndPrgm getMode("Base") → oldbase show("", {a, b}) show("And ", a and b) show("Or ", a or b) show("Xor ", a xor b) show("Not ", not a) Pause "[Press ENTER]" show("LSh ", shift(a,b)) show("RSh ", shift(a,–b)) show("LRo ", rotate(a,b)) show("RRo ", rotate(a,–b)) setMode("Base",oldbase)EndPrgma ← 10b ← 2# Experimental!¬a # bitwise NOT°⋯ /× ⋯ ⊟ a b # bitwise AND°⋯ /∨ ⋯ ⊟ a b # bitwise OR°⋯ /≠ ⋯ ⊟ a b # bitwise XOR* a ⁿ:2 b # SHL⌊÷: a ⁿ:2 b # ASR
¯92108402
%\n { 0a } %\s { 20 } %\0 { 00 }%newline { [ LIT2 \n -Console/write ] DEO }%not { #ff EOR }%and { AND }%or { ORA }%xor { EOR }%shl { #40 SFT SFT }%shr { SFT }%rol { #40 SFT #00 ROT ROT SFT2 ORA }%ror { SWP #00 ROT SFT2 ORA }|18 @Console/write|100#0a02DUP2 SWP ;msgs/a print/arg ;msgs/b print/argbitwiseBRK@bitwise ( a b -- );msgs/not print/str ;msgs/a print/str ;msgs/equ print/str OVR not print/result;msgs/and print/label DUP2 and print/result;msgs/or print/label DUP2 or print/result;msgs/xor print/label DUP2 xor print/result;msgs/shl print/label DUP2 shl print/result;msgs/shr print/label DUP2 shr print/result;msgs/rol print/label DUP2 rol print/result;msgs/ror print/label ror !print/result@print/label ( label* -- );msgs/a /str/str;msgs/b /str;msgs/equ !/str@print/byte ( byte -- )[ LIT "$ ] .Console/write DEODUP #04 SFT /nibble( >> )@print/nibble ( -- )#0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD .Console/write DEOJMP2r@print/arg ( a name* -- )/str ;msgs/equ /str( >> )@print/result ( a -- )/byte newlineJMP2r@print/str ( str* -- )LDAk .Console/write DEOINC2 LDAk ?/strPOP2 JMP2r@msgs [&a "a \s \0&b "b \s \0&equ "= \s \0¬ "NOT \s \0&and "AND \s \0&or "OR \s \0&xor "XOR \s \0&shl "SHL \s \0&shr "SHR \s \0&rol "ROL \s \0&ror "ROR \s \0 ]a = $0ab = $02NOT a = $f5a AND b = $02a OR b = $0aa XOR b = $08a SHL b = $28a SHR b = $02a ROL b = $28a ROR b = $82
void testbit(int a, int b) { print(@"input: a = $a, b = $b\n"); print(@"AND: $a & $b = $(a & b)\n"); print(@"OR: $a | $b = $(a | b)\n"); print(@"XOR: $a ^ $b = $(a ^ b)\n"); print(@"LSH: $a << $b = $(a << b)\n"); print(@"RSH: $a >> $b = $(a >> b)\n"); print(@"NOT: ~$a = $(~a)\n"); /* there are no rotation operators in vala, but you could define your own function to do what is required. */}void main() { int a = 255; int b = 2; testbit(a,b); }input: a = 255, b = 2AND: 255 & 2 = 2OR: 255 | 2 = 255XOR: 255 ^ 2 = 253LSH: 255 << 2 = 1020RSH: 255 >> 2 = 63NOT: ~255 = -256
In VBA, the logical operators And, Or, Xor, Not are actually binary operators. There are also Eqv and Imp (for bitwise "equivalence" and "logical implication").
Debug.Print Hex(&HF0F0 And &HFF00) 'F000Debug.Print Hex(&HF0F0 Or &HFF00) 'FFF0Debug.Print Hex(&HF0F0 Xor &HFF00) 'FF0Debug.Print Hex(Not &HF0F0) 'F0FDebug.Print Hex(&HF0F0 Eqv &HFF00) 'F00FDebug.Print Hex(&HF0F0 Imp &HFF00) 'FF0F
The other operations in the task are not builtin, but are easy to implement. Integers are signed, and overflow throws and exception, one must take care of this.
Function MaskL(k As Integer) As Long If k < 1 Then MaskL = 0 ElseIf k > 31 Then MaskL = -1 Else MaskL = (-1) Xor (2 ^ (32 - k) - 1) End IfEnd FunctionFunction MaskR(k As Integer) As Long If k < 1 Then MaskR = 0 ElseIf k > 31 Then MaskR = -1 Else MaskR = 2 ^ k - 1 End IfEnd FunctionFunction Bit(k As Integer) As Long If k < 0 Or k > 31 Then Bit = 0 ElseIf k = 31 Then Bit = MaskL(1) Else Bit = 2 ^ k End IfEnd FunctionFunction ShiftL(n As Long, k As Integer) As Long If k = 0 Then ShiftL = n ElseIf k > 31 Then ShiftL = 0 ElseIf k < 0 Then ShiftL = ShiftR(n, -k) Else ShiftL = (n And MaskR(31 - k)) * 2 ^ k If (n And Bit(31 - k)) <> 0 Then ShiftL = ShiftL Or MaskL(1) End IfEnd FunctionFunction ShiftR(n As Long, k As Integer) As Long If k = 0 Then ShiftR = n ElseIf k > 31 Then ShiftR = 0 ElseIf k < 0 Then ShiftR = ShiftL(n, -k) Else ShiftR = (n And MaskR(31)) \ 2 ^ k If (n And MaskL(1)) <> 0 Then ShiftR = ShiftR Or Bit(31 - k) End IfEnd FunctionFunction RotateL(n As Long, k As Integer) As Long k = (32768 + k) Mod 32 If k = 0 Then RotateL = n Else RotateL = ShiftL(n, k) Or ShiftR(n, 32 - k) End IfEnd FunctionFunction RotateR(n As Long, k As Integer) As Long k = (32768 + k) Mod 32 If k = 0 Then RotateR = n Else RotateR = ShiftR(n, k) Or ShiftL(n, 32 - k) End IfEnd FunctionFunction ClearBit(n As Long, k As Integer) As Long ClearBit = n And Not Bit(k)End FunctionFunction SetBit(n As Long, k As Integer) As Long SetBit = n Or Bit(k)End FunctionFunction SwitchBit(n As Long, k As Integer) As Long SwitchBit = n Xor Bit(k)End FunctionFunction TestBit(n As Long, k As Integer) As Boolean TestBit = (n And Bit(k)) <> 0End Function
Examples
Debug.Print Hex(MaskL(8)) 'FF000000Debug.Print Hex(MaskR(8)) 'FFDebug.Print Hex(Bit(7)) '80Debug.Print Hex(ShiftL(-1, 8)) 'FFFFFF00Debug.Print Hex(ShiftL(-1, -8)) 'FFFFFFDebug.Print Hex(ShiftR(-1, 8)) 'FFFFFFDebug.Print Hex(ShiftR(-1, -8)) 'FFFFFF00Debug.Print Hex(RotateL(65535, 8)) 'FFFF00Debug.Print Hex(RotateL(65535, -8)) 'FF0000FFDebug.Print Hex(RotateR(65535, 8)) 'FF0000FFDebug.Print Hex(RotateR(65535, -8)) 'FFFF00
identical syntax as in#VBA.
Sub Test(a as Integer, b as Integer) WriteLine("And " & a And b) WriteLine("Or " & a Or b) WriteLine("Xor " & a Xor b) WriteLine("Not " & Not a) WriteLine("Left Shift " & a << 2) WriteLine("Right Shift " & a >> 2)End SubVisual Basic doesn't have built-in support for bitwise rotation.
In Wren all numbers are represented in 64-bit floating point form.
Although the same bitwise operators are supported as in C, the operands are converted to unsigned 32-bit integers before the operation is performed and return values of this form.
Consequently, it is not usually a good idea to try and perform bitwise operations on integer values outside this range or on non-integral values.
Given this limitation, there is no difference between logical and arithmetic left and right shift operations. Although Wren doesn't support circular shift operators, it is not difficult to write functions to perform them.
var rl = Fn.new { |x, y| x << y | x >> (32-y) }var rr = Fn.new { |x, y| x >> y | x << (32-y) }var bitwise = Fn.new { |x, y| if (!x.isInteger || !y.isInteger || x < 0 || y < 0 || x > 0xffffffff || y > 0xffffffff) { Fiber.abort("Operands must be in the range of a 32-bit unsigned integer") } System.print(" x = %(x)") System.print(" y = %(y)") System.print(" x & y = %(x & y)") System.print(" x | y = %(x | y)") System.print(" x ^ y = %(x ^ y)") System.print("~x = %(~x)") System.print(" x << y = %(x << y)") System.print(" x >> y = %(x >> y)") System.print(" x rl y = %(rl.call(x, y))") System.print(" x rr y = %(rr.call(x, y))")}bitwise.call(10, 2)x = 10 y = 2 x & y = 2 x | y = 10 x ^ y = 8~x = 4294967285 x << y = 40 x >> y = 2 x rl y = 40 x rr y = 2147483650
It must be linked with the libc and "start" code; lazyly agcc bitops.o works, being bitops.o produced bynasm -f elf bitops.asm (I've chosen ELF since I am on a GNU/Linux box)
extern printfglobal mainsection .textmainmoveax, dword [_a]movecx, dword [_b]pushecxpusheaxand eax, ecxmovebx, _opandcallout_opscallget_numsoreax, ecxmovebx, _oporcallout_opscallget_numsxor eax, ecxmovebx, _opxorcallout_opscallget_numsshreax, clmovebx, _opshrcallout_opscallget_numsshleax, clmovebx, _opshlcallout_opscallget_numsroleax, clmovebx, _oprolcallout_opscallget_numsroreax, clmovebx, _oprorcallout_opscallget_numssaleax, clmovebx, _opsalcallout_opscallget_numssareax, clmovebx, _opsarcallout_opsmoveax, dword [esp+0]noteaxpush eaxnoteaxpusheaxpush_opnotpush_nullpush_testncallprintfaddesp, 20addesp, 8retout_opspusheaxpushecxpushebxpushdword [_a]push_testcallprintfaddesp, 20retget_numsmoveax, dword [esp+4]movecx, dword [esp+8]retsection .data_add11_bdd3section .rodata_testdb'%08x %s %08x = %08x', 10, 0_testndb'%08s %s %08x = %08x', 10, 0 _opanddb'and', 0_opordb'or ', 0_opxordb'xor', 0_opshldb'shl', 0_opshrdb'shr', 0_oprordb'ror', 0_oproldb'rol', 0_opnotdb'not', 0_opsaldb'sal', 0_opsardb'sar', 0_nulldb 0end
PROGRAM "bitwise"DECLARE FUNCTION Entry()INTERNAL FUNCTION ULONG Rotr(ULONG x, ULONG s)FUNCTION Entry() SLONG a, b ULONG ua, ub a = 21 b = 3 ua = a ub = b PRINT PRINT "= Decimal =" PRINT LTRIM$(STR$(a)); " AND"; b; ":"; a & b ' also: a AND b PRINT LTRIM$(STR$(a)); " OR"; b; ":"; a | b ' also: a OR b PRINT LTRIM$(STR$(a)); " XOR"; b; ":"; a ^ b' also: a XOR b PRINT "NOT"; a; ":"; ~a ' also: NOT a PRINT LTRIM$(STR$(a)); " <<<"; b; ":"; a <<< b ' arithmetic left shift PRINT LTRIM$(STR$(a)); " >>>"; b; ":"; a >>> b ' arithmetic right shift PRINT LTRIM$(STR$(ua)); " <<"; b; ":"; ua << b ' bitwise left shift PRINT LTRIM$(STR$(ua)); " >>"; b; ":"; ua >> b ' bitwise right shift PRINT LTRIM$(STR$(ua)); " rotr"; ub; ":"; Rotr(ua, ub) PRINT PRINT "= Binary =" PRINT BIN$(a); " AND "; BIN$(b); ": "; BIN$(a & b) PRINT BIN$(a); " OR "; BIN$(b); ": "; BIN$(a | b) PRINT BIN$(a); " XOR "; BIN$(b); ": "; BIN$(a ^ b) PRINT "NOT "; BIN$(a); ": "; BIN$(~a) PRINT BIN$(a); " <<< "; BIN$(b); ": "; BIN$(a <<< b) PRINT BIN$(a); " >>> "; BIN$(b); ": "; BIN$(a >>> b) PRINT BIN$(ua); " << "; BIN$(b); ": "; BIN$(ua << b) PRINT BIN$(ua); " >> "; BIN$(b); ": "; BIN$(ua >> b) PRINT BIN$(ua); " Rotr "; BIN$(ub); ": "; BIN$(Rotr(ua, ub))END FUNCTION' Rotate x to the right by s bitsFUNCTION ULONG Rotr(ULONG x, ULONG s) RETURN (x >> s) | (x << (SIZE(ULONG) * 8 - s))END FUNCTIONEND PROGRAM
= Decimal =21 AND 3: 121 OR 3: 2321 XOR 3: 22NOT 21:-2221 <<< 3: 16821 >>> 3: 221 << 3: 16821 >> 3: 221 Rotr 3: 2684354562= Binary =10101 AND 11: 110101 OR 11: 1011110101 XOR 11: 10110NOT 10101: 1111111111111111111111111110101010101 <<< 11: 1010100010101 >>> 11: 1010101 << 11: 1010100010101 >> 11: 1010101 Rotr 11: 10100000000000000000000000000010
(defun bitwise-operations (a b); rotate operations are not supported(print `(,a and ,b = ,(logand a b)))(print `(,a or ,b = ,(logior a b)))(print `(,a xor ,b = ,(logxor a b)))(print `(,a left shift by ,b = ,(lsh a b)))(print `(,a right shift by ,b = ,(lsh a (- b)))) ; negative second operand shifts right(print `(,a arithmetic right shift by ,b = ,(ash a (- b)))) )
Text(0, "A and B = "); HexOut(0, A and B); CrLf(0); \alternate symbol: &Text(0, "A or B = "); HexOut(0, A or B); CrLf(0); \alternate symbol: !Text(0, "A xor B = "); HexOut(0, A xor B); CrLf(0); \alternate symbol: |Text(0, "not A = "); HexOut(0, not A); CrLf(0); \alternate symbol: ~Text(0, "A << B = "); HexOut(0, A << B); CrLf(0);Text(0, "A >> B logical = "); HexOut(0, A >> B); CrLf(0);Text(0, "A >> B arithmetic = "); HexOut(0, A ->> B); CrLf(0);\Rotate operations must be done by calling a function such as:func ROR(A, B); int A, B; return A>>B ! A<<(32-B);Text(0, "A ror B = "); HexOut(0, ROR(A,B)); CrLf(0);
The reason the "!" and "|" symbols may seem reversed is that the ORoperator was introduced at a time when only uppercase characters wereavailable (such as on the Apple II). The XOR operator was added later.
sub formBin$(n) return right$("00000000" + bin$(n), 8)end suba = 6 : b = 3print a, " = \t", formBin$(a)print b, " = \t", formBin$(b)print "\t--------"print "AND = \t", formBin$(and(a, b))print "OR = \t", formBin$(or(a, b))print "XOR = \t", formBin$(xor(a, b))print "NOT ", a, " =\t", formBin$(xor(255, a))6 =000001103 =00000011--------AND =00000010OR =00000111XOR =00000101NOT 6 =11111001
LD A,&05AND &1F ;0x05 & 0x1F
LD A,&05OR &1F ;0x05 | 0x1F
LD A,&05XOR &1F ;0x05 ^ 0x1F
LD A,&05CPL
LD A,&05SLA A
LD A,&05SRL A
LD A,&05SRA A
Z80 has two different types of bit rotates.
RL/RR rotates through the carry. The state of the carry before the rotate gets rotated in, and the bit that rotates out is put into the carry.RLC/RRC copies the bit "pushed out" to the carry but the old carry isn't rotated in.LD A,&05RLALD A,&05RRALD A,&05RLCALD A,&05RRCA
No bitwise rotates. Shifts are unsigned.
(7).bitAnd(1) //-->1(8).bitOr(1) //-->9(7).bitXor(1) //-->6(1).bitNot() : "%,x".fmt(_) //-->ff|ff|ff|ff|ff|ff|ff|fe(7).shiftRight(1) //-->3(7).shiftLeft(1) //-->0xe(-1).toString(16) //-->ffffffffffffffff(-1).shiftRight(1).toString(16) //-->7fffffffffffffff