3D Gallery with Great Artwork Imagine Logo with Three Colors Beach Cabin 3D Android Tablet with Different Screens Studio Apartment Red Figured Greek Vase on Blue Background Silver and Gold Flashlight Lake on Fire

JavaScript: Logic

Page 8

Logic: Bitwise & Triple Equals Operators

Introduction === Versus == !== Versus != Bitwise &, |, ^, ~ AND OR XOR NOT Twos Complement Bitwise <<,>>,>>> JavaScript File: binary.js JavaScript File: logic.js Summary

Introduction

Learn about triple digit and bitwise operators. Learn to use triple equals signs, exclamation with double equals signs, bitwise AND, OR, NOT, XOR, Zero Filled Left and Right Shift, Signed Right Shift Operators. Compare objects with two versus three digit operators such as ===, !== versus ==, !=. Bitwise operators are represented with &&, ||, ~, ^, >>, << and >>>.

=== Versus ==

If two objects are the same object, they are equal with ===. If two primitives are the same value, they are equal with both === and ==.

Two different objects, regardless of their value, will always return false with ===. Two different primitives, with the same value will always return true with either === or ==.

Object Triple Equal Comparison

The difference between comparisons with === versus == is that the first comparison must match in both value and object. The second comparison must only match in value.

The following two examples create two objects, with the same property value. However the green box compares the same objects. The blue box compares similar objects, with the same values, but they're not the same objects.

Therefore the blue box returns false and the green box returns true.

Click For === Distinct Objects

function compareSameValueDiffObjects(){
let objThree = new Object();
objThree.n = 3;
let objThreeAlso = new Object();
objThreeAlso.n = 3;
return (objThree === objThreeAlso);
}

Click For === Same Objects

function compareSameValueSameObjects(){
let objThree = new Object();
objThree.n = 3;
let objThreeAlso = new Object();
objThreeAlso.n = 3;
objThreeAlso = objThree;
return (objThree === objThreeAlso);
}

Primitive Triple Equal Comparison

The following code just compares primitive objects, numbers, with the same values. The triple equal signs return true for different primitive variables, with the same values.

My conclusion is that triple equal signs only make a difference when comparing objects, not primitives.

Click For === Distinct Objects

function compareSameValueDiffNumbers(){
let nA = 7;
let nB = 7;
return (nA === nB);
}

Click For === Same Objects

function compareSameValueSameNumbers(){
let nA = 7;
let nB = 7;
return (nA == nA);	
}

Symbol Triple Equal Comparison

The following code compares different symbols with the same values. The triple equal signs return false for both.

My conclusion is that Symbols, despite being primitives, are always different objects. Apparently symbols are useful for security because malware cannot create and use fake symbols with the same name and value.

Click For === Distinct Symbols Local Versus Global

function compareSameValueDiffSymbols(){
// Local:
let sD1 = Symbol('keyname');
// Global:
let sD2 = Symbol.for('keyname');
return (sD1 === sD2);
}

Click For === Same Value & Symbol

compareSameValueDiffSymbolsLocal(){
sD1 = Symbol('d')
sD2 = Symbol('d')
return (sD1 === sD2);	
}

!== Versus !=

We can use the triple equal signs above, to learn about the double not equal sign, !==. For two different primitives, with the same values, !== should return false. For two different objects, with the same values, !== should return true. For two different Symbols, with the same values, !== should return true.

Object NOT Triple Equal Comparison

The difference between comparisons with !== versus != is that the first comparison must not match in either value or object. The second comparison must not match in value only.

Arrays Triple Not Equal

The following two examples create two arrays, with the same value for the first entry. However the green box compares each array, and each array's first entry, with !=. The blue box compares each array, and each array's first entry, with !==.

The results are identical because both compare one array's value against another array's value. The second compares one array's first primitive entry against another array's first primitive entry.

Click For !== Distinct Objects

function tripleNOTEqualCompareNOTSameValueDiffArrays()(){
let a1 = new Array(1);
a1[0] = 3;
let a2 = new Array(1);
a2[0] = 3;
// Comparing objects, comparing primitives:
return [(a1 !== a2),(a1[0] !== a2[0])];
}

Click For != Distinct Objects

function doubleNOTEqualCompareNOTSameValueDiffArrays()(){
let a1 = new Array(1);
a1[0] = 3;
let a2 = new Array(1);
a2[0] = 3;
// Comparing objects, comparing primitives:
return [(a1 != a2),(a1[0] != a2[0])];
}

Summary: ===, !== Versus ==, !=

Neither operator makes a difference when comparing primitives. The triple digit operators help code determine if you're using the same object in memory. Symbols are the exception. New symbols, despite having the same values, are always different in value and in object (or memory).

Bitwise &, |, ^, ~

Page five provided a brief overview of bitwise operators with JavaScript. This section includes interactive bitwise operations with more detailed discussion.

JavaScript bitwise operations perform on 32 bit numbers. Consider each number as thirty two digits. Each digit's either a zero or a one.

We'll use smaller numbers to display operations. However bear in mind, operations are performed on 32 bits, or eight sets of four bits.

Behind the Scenes Conversion

JavaScript converts 64 bit floating point numbers to 32 bit signed binary integers, for bitwise operations, performs the bitwise operation, then converts the result back to a 64 bit floating point number.

Signed binary numbers include both positive and negative values. If the farthest left bit equals one, then the number is negative. If the farthest left bit equals zero, then the number is positive. However we need to take the twos complement to accomplish signed binary bitwise operations.

& Means AND

The & compares each bit, in positiion. If both bits equal one, then a one is returned for the bit in that position. If either bit is a zero, then a zero is returned.

Example &

AND two positive numbers. 7 AND 4 equals four because 22 equals four.

In this case 4 behaves like a mask, to remove every binary digit from 7 that doesn't match ones.

0111 & 0100 = 0100

0111
0100
----
0100

AND two positive numbers. The result of 5 AND 8 equals 0.

In this case 5 and 8 behave like masks against each other, to remove every binary digit that doesn't match ones. You might find masks very handy while developing various applications.

0101 & 1000 = 0000

0101
1000
----
0000

Click a Box

The following examples demonstrate applying AND to positive numbers and positive binary digits. Declare two binary digits representing 5 and 8, with 0b0101, 0b1000. When using binary numbers keep the number of digits identical. It's assumed they are positive numbers, regardless of the left most digit.

You can also allow the JavaScript interpreter to convert positive decimal digits to binary digits, perform AND on those digits, then return a negative result. See the violet box, below. See the binary.js source code.

However twos complement performs accurate binary operations on negative numbers.

7 AND 4

function SevenANDFour(){
return (7 & 4);
}

5 AND 8

function FiveANDEight(){
return (0b0101 & 0b1000);
}

-7 AND -5

function NegateSevenANDFive(){
return -(7 & 5);
}

-7 AND -5

function NegateSevenANDFiveBinary(){
return -(0b111 & 0b101);
}

| Means OR

The | compares each bit, in positiion. If either bits equal one, then a one is returned for the bit in that position.

Example |

OR two positive numbers. They equal seven because
20 equals 1 plus
21 equals 2 plus
22 equals 4.
1 + 2 + 4 = 7

0111 | 0100 = 0111

0111
0100
----
0111

^ Means XOR

The ^ compares each bit, in positiion. If the bits are different, the result returns one.

Example ^

XOR two positive numbers. The result equals three.

0111 | 0100 = 0011

0111
0100
----
0011

XOR two negative numbers. Assuming we're only using four bit numbers and the left most bit is the signed bit. The the result equals positive one.

1101 | 1111 = 0001

1101
1100
----
0001

~ Means NOT

NOT inverts all bits on one number. NOT is a unary operator.

NOT might prove useful in some applications, especially graphics filters. However NOT is most useful in twos complement operations, below.

Perform not on 1101, which equals = nine. The result equals two.

~1101 = 0010

The following, Twos Complement examples include the NOT operation.

Twos Complement

To accomplish bitwise operations on negative numbers, in binary format, we need to take the twos complement. Negative bits are stored like a bitwise NOT, plus a one. Therefore take the opposite digit, from each bit on a binary number, then add one.

Tap the following two boxes to see that twos complement works for both binary and decimal numbers, with JavaScript. I suspect the binary operation, ~d1, causes the JavaScript interpreter to convert all decimal numbers to binary, then back again to decimal.

Twos Complement of Binary Positive 4

Call TwosComplementConvert(0b100)
function TwosComplementConvert(d){
let d2 = d;
let d3 = ~d2 + 1;
return d3;
}

Twos Complement of Decimal Positive 7

Call TwosComplementConvert(7)
function TwosComplementConvert(d){
let d2 = d;
let d3 = ~d2 + 1;
return d3;
}

Twos Complement AND, OR

Now we can AND or OR bitwise operations on negative numbers.

Twos Complement AND:

Twos Complement on 7 AND 3

called as
ANDNegateTwoDigits(7,3)

AND
111
011
___
011 = 3

Negation = -3.

function ANDNegateTwoDigits(b1, b2){
let v1 = b1 & b2;
let v2 = TwosComplementConvert(v1);

// See bottom of page
// for debugging output.
displayValues(v1,v2,true);

return (v2);
}

Twos Complement on 4 OR 6.

called as
ANDNegateTwoDigits(4,6)

AND
100
110
___
100 = 4

Negation = -4.

function ANDNegateTwoDigits(b1, b2){
let v1 = b1 & b2;
let v2 = TwosComplementConvert(v1);

displayValues(v1,v2,true);

return (v2);
}

Twos Complement OR:

Twos Complement on 7 OR 3

called as
ORNegateTwoDigits(7,3)

OR
111
011
___
111 = 7

Negation = -7.

function ORNegateTwoDigits(b1, b2){
let v1 = b1 | b2;
let v2 = TwosComplementConvert(v1);
return (v2);
}

Twos Complement on 4 AND 6

called as
ORNegateTwoDigits(4,6)

OR
100
110
___
110 = 6

Negation = -6.

function ORNegateTwoDigits(b1, b2){
let v1 = b1 | b2;
let v2 = TwosComplementConvert(v1);
return (v2);
}

Bitwise <<,>>,>>>

Bitwise shifts apply less than and greater than operators. Bit shifts represent moving bits over toward the left or toward the right. The first operand represents the number to modify. The second operand represents the number of bits to shift, either right or left.

Left pointing bit shift operators << shift bits to the left. Right pointing bit shift operators >>> shift bits to the right. In both cases, emptied bit locations receive zeros.

Two right pointing bit shift operators >>, maintain the sign bit, whether it represents negative, 1, or positive, 0.

Multiply Or Divide

Bitwise operations first convert numbers to integers in binary format. When shifting left you're multiplying by two, for every digit shifted. When shifting right, you're dividing by two, for every digit shifted.

However with divisions, shifting right, your number loses digits, as they fall off to the right. With multiplications, shifting left, your number loses digits, as they fall off to the left, if the resulting value would require more than 32 bits.

Zero Filled Left Shift: <<

<< this operator represents a zero fill left shift. In otherwords, every binary digit shifts left by the number of spaces indicated with the second operand. The vacated digits, on the right, are filled with zeros. The farthest left digits disappear.

This usually results in a multiplication by two, for each shift left. If you shift by one, then the left value multiplies by two. If you shift by two, then the left value multiplies by four, etc.

However, when the left most digits fall off then the value decreases. If your resulting binary value exceeds 32 bits, then your result loses left binary digits.

Zero filled Left Shift

called as
ShiftLeftZeroFill(7,2)

000111 << 000010  = 011100;

Result = 10;

function ShiftLeftZeroFill(b1,b2){
return (b1 << b2);
}

Zero filled Left Shift

called as
ShiftLeftZeroFill(0b1011,0b0001)

// 11 times 2:
1011 << 1 = 10110;

Result = 22;

function ShiftLeftZeroFill(b1,b2){
return (b1 << b2);
}

Signed Right Shift >>

Shifts right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off.

Signed Bit Shift

The green box, highlights the concept of signed right bit shifts. If the sign bit on the left operand equals one, then it's a negative number. In that case, you're shifting a twos complement number.

In the green box the operation shifts a negative seven. That means 0b0111 = +7 becomes 0b1001 = -7, with the twos complement operation.

Move the bits over two values to the right. 0b1001 becomes 0b10 = +2. Code fills in the sign bit, giving us negative two.

However signed right shifts are fairly simple when the left most bit is a zero. Then we don't need to convert to two's complement to understand how the shift operates.

Signed Right Shift

called as
ShiftRightSigned(7,2)

000111 >> 000010  = 000001;

Result = 1

function ShiftRightSigned(b1,b2){
return (b1 >> b2);
}

Signed Right Shift

called as
ShiftRightSigned(0b1011,0b0001)

// Binary numbers
// with less than 32bits
// seem to be considered positive.
// Result = 0b01010.
Result = 6.

function ShiftRightSigned(b1,b2){
return (b1 >> b2);
}

Signed Right Shift

called as
ShiftRightSigned(-7,2)

// Twos complement -7
// 0b0111 becomes 0b1001.
// Shift right twice: 0b10 = 2.
// Keep sign bit = -2.

Result = -2

function ShiftRightSigned(b1,b2){
return (b1 >> b2);
}

Signed Right Shift

called as
ShiftRightSigned(0b1011,0b0001)
// 11 >> 1
// Again binary numbers, less
// than 32 bits in length
// are considered positive.
1101 >> 0001 = 0110;

Result = 6.

function ShiftRightSigned(b1,b2){
return (b1 >> b2);
}

Zero Filled Right Shift >>>

The zero filled right shift might be the easiest bit shift to understand. For the most part, you're just dividing a number by multiples of two. The right operand tells us how many multiples of two.

Zero filled Right Shift

called as
ShiftRightZeroFill(7,2)

000111 >> 000010  = 00001;

Result = 1;

function ShiftRightZeroFill(b1,b2){
return (b >> b2);
}

Zero filled Left Shift

called as
ShiftRightZeroFill(0b1011,0b0001)

// 11 divided by 2
// and losing the right most bit.
1011 >> 1 = 10110;

Result = 5;

function ShiftRightZeroFill(b1,b2){
return (b << b2);
}

Debugging Output

Summary

You learned about triple digit operators and bitwise operators. You compared objects with two versus three digit operators such as ===, !== versus ==, !=. You learned to use bitwise AND, OR, NOT, XOR, Zero Filled Left and Right Shift, Signed Right Shift. Bitwise operators are represented with &&, ||, ~, ^, >>, << and >>>.

Learn JavaScript

JavaScript's the foundation of Web developer and Website design skills. This free and unique JavaScript tutorial includes some new or seldom used, but useful features.

Tags
canvas drawing, web design, web designing course, how to become a web developer, coding websites, website developers,learning web design, html web design, html5 canvas tutorials, coding Website, html5 canvas, learn to code, html5 canvas tutorial,learn html tutorial, simple html tutorial

Ads >
Create 3D Games: Learn WebGL Book 2 Simple Shaders: Learn WebGL Book 4
3D Programming for Beginners: Learn WebGL Book 1

for Web graphics!

Copyright © 2022 Amy Butler. All Rights Reserved.