Javascript and Bitmasks

I thought this might be an easier way to do some filtering
Basically 5 star gradings so 1,2,4,8,16
And 6 property types so 32,64,128,256,512,1024

In the js I add the selections together and check it against the bitmask on the elements.
For the star rating it works fine but selecting a property type does not have the desired effect.
Maybe I'm understanding this wrong but if I select 5 star properties then only 5 stars are shown.
If I then select property type 2 then I have a total of 80 but the remaining elements which have bit of 48 (5 star & property type 1) are still showing.
LVL 58
Who is Participating?
Slick812Connect With a Mentor Commented:
greetings  GaryC123, , I have done much with setting and retrieving Bits (bitmask) in an integer, Your problem is how you evaluate the Result (I guess it's sumStar), you have -
sumStar & temp

and the temp  comes from temp=$(this).attr("data-mask");
I really can NOT tell what you need to do, because the data-mask is not known to me, nor is the sumStar value, but I will give you some examples on how to use  &  and get "Sections" of bits from a muti carrier like you have in sumStar (has bits for star and property)
if you use -
var starV =  sumStar & 31;
The starV will have JUST the lower bits  1,2,4,8,16 , but NONE higher than 16

if you use -
var propV =  sumStar & !31;
you should get the higher bits and NOT the lower

OR if you need to be more specific you use -
var propV =  sumStar & 2016;
you should get the higher bits to 1024 and NOT the lower

just to mention, if you are combining BITS you should NOT use addition, you should use the OR as |
sumStar |= bitValue;
Dave BaldwinFixer of ProblemsCommented:
Without code, that doesn't really make any sense.
Ray PaseurConnect With a Mentor Commented:
I think I might approach this a little differently.  Bitmasks made sense when the cost of storage was relatively high, but they make for complicated programming.  Today, carrying two integers instead of a bitmask would be more reasonable to me.  One integer would carry the value of the star rating and the other integer would carry the property type.

An example of star ratings is available here:

A brief summary of storage costs goes something like this (true story).  I sold my first computer disk storage drives in the late 1970's.   These machines were about the size of a washing machine.  They stored 100MB and cost $35,000 each.  With my first commission check, I went out and bought a Mercedes-Benz which coincidentally cost about $35,000.  Over the decades the cost of storage has declined rather dramatically.  Today, 100MB is a rounding error in the capacity of most storage devices. A gigabyte (1,024 washing machines) costs about the same as a few sheets of toilet paper, and any device that only stores 1GB is considered obsolete.  If the Mercedes-Benz product had been on the same price-performance curve as the computer storage product, you would be able to buy a new luxury car today for less than a dime, use it for three years and throw it away.  Your replacement Mercedes would be expected to cost about a nickel.

So that's why I don't think very much about optimizing data structures to save one byte when two bytes will make my programming easier to understand, write and debug.

Best to all, over and out, ~Ray
Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to and use offer code ‘EXPERTS’ to get 10% off your first purchase.

GaryAuthor Commented:
I understand what you are saying Ray, I was thinking this might be easier to filter elements based on around 25 possible filters instead of having checks for each group of filters.
Example page is here

Change the star rating selection around and it works fine.
Add in the property type and it doesn't work properly.

Code to get the sum of the selections is
$(".starrating input[type=checkbox]:checked").each(function(){
      sumStar += parseInt($(this).val());
$(".accommtype input[type=checkbox]:checked").each(function(){
      sumStar += parseInt($(this).val());
var temp=$(this).attr("data-mask");

Open in new window

And the show/hide - nothing special here
if(sumStar & temp){

Open in new window

GaryAuthor Commented:
LOL - think I'm more confused, must be 20 years since I looked at bitmasks last.

The bitmask works great for the star rating - click 5 star and only 5 stars are shown, click 4 star and the 4 stars show as well and so on.
If I click a property type - then it gets screwed up.
The property elements on that page have a data-mask which is one of the following - 48, 40, 36, 520
When you click a star rating or property type, you will get a popup of the total value of the bits - in the case of 5 stars that are hotels then this would be a value of 48

Now my understanding is, taking for example a 5 star hotel with a bit value of 48 (16+32), if I compare that value against the bitmask on the properties I should only get ones with a bitmask of 48 - properties with a bitmask of 40 shouldn't show
Sorry, I do NOT understand your BIT math for what you say.  So it seems that your "property" values, do not have any meaning to me, I do not believe that you have the correct IDEA about how and why positional BIT setting works.
you say = "only get ones with a bitmask of 48 - properties with a bitmask of 40 shouldn't show"
this is INCORRECT ! !
The & bit math operator used here -
if(sumStar & temp)
will return TRUE with -
if(48 & 48)
ALSO will return TRUE with -
if(48 & 40)
ALSO will return TRUE with -
if(48 & 36)

 the way I do bits is like -
sumStar  HAS TO BE evaluated on JUST ONE BIT value either 1,2, 4, 8, 16, or 32, , you CAN NOT combine values such as 40 (40 has two BITS 8 and 32)
It may be that you are trying To ADD the Bits from these two -
$(".starrating input[type=checkbox]:checked").each(function(){
      sumStar += parseInt($(this).val());
$(".accommtype input[type=checkbox]:checked").each(function(){
      sumStar += parseInt($(this).val());

and get some sort of value Sum, that if starrating is 2 stars and the accommtype is 1 star, then the sumStar is 3 stars, which will NOT WORK for Single BIT evaluations.
I guess you could adapt a If Only evaluation
if((sumStar & temp) == 48) { // ONLY true if sumStar & temp are Both 48, then Do Five star code here
if(sumStar == 48)

this really does NOT use any of the advantages of BIT evaluation, as I said you can NOT use addition in setting Bits
GaryAuthor Commented:
Still not following this.
Yes I am trying to add the two bits. But I am already adding the bits from the star ratings performed here - you say you cannot do it that way...
$(".starrating input[type=checkbox]:checked").each(function(){
      sumStar += parseInt($(this).val());

No matter what selection of stars I click the correct ones show up (sum of the combination of any of 1,2,4,8,16), if I select 3 star and 5 star then only 3 and 5 stars show up and all others are hidden.
This is where I'm getting lost because why when I extend the bits to 32 it stops working.
GaryAuthor Commented:
If I select 3 star and 5 star then I have a total bit of 20 (16+4)
I compare this against the mask and the mask needs to be able to contain 16 or 4 (these are the real values of the bitmask on the elements) -

48 is true - 32+16 (matched 16)
40 is false - 32+8 (no match)
36 is true - 32+4 (matched 4)
520 is false - 512+8 (no match)
260 is true - 256+4 (matched 4)

If I add 32 to the bit sum so I have 52 then there is only two possible combinations  -
48 and 36.
GaryAuthor Commented:
Ok it's clicked!
My logic is sound in that I'm adding the values - but I was missing the point that I was filtering on two different groups - stars and property type. So when property type matched it didn't matter what star rating it was.
If you ADD the numbers as a BIT reference, you can get values that did not exist before, if both are 4, then you add 4 + 4 to get 8, and 8 is a BIT that was not set before, unlike if you add 2 and 4 you get 6, the 2 bit is set and the 4 bit is set, both were in the bits that came into the equation.
if you stick with adding the numbers, you need to evaluate the addition sum in a different manner, some sort of switch evaluation may can do? But if you use addition, you may as well convert to regular math and not use the bit positions?
you might should use the OR for combining the bits, it will NOT place any BIT like 8 above, that did not exist before, But I was hoping to figure out what you were trying to do, and offer a suggestion on how to do it, But I only get baffled by your statements,
I can see the result value of 20 in "If I select 3 star and 5 star", but I do not know what this 20 has a difference significance than just 16, as you can not go higher than 5 star?
you might consider for Just the 5 star ratings -
var b = parseInt($(this).val());
if (b > sumStar) sumStar = b; // Gets only the highest rating
GaryAuthor Commented:
I don't think I can make it any clearer than above.
What I realised is, the code was working for the bitmask comparison - but once I added the property types in as well to the same code I wasn't taking account of the fact that it was doing what it is supposed to, in that if any of the bits of my total BIT can be applied to the bitmask then show it - it only needed either the property type OR the star type to be possible.
So in the case of 5 star hotels, the sum of my bits is 48 - when comparing it to the bitmask it was matching 5 stars and/or hotels - this is where I was falling down.
Seperating the check so it now looks like this
if((sumStar & temp) && (sumProperty & temp)
means it has to match the stars and the property type
GaryAuthor Commented:
Even though I kind of came to the answer myself it's worthy to award the points for the time put in explaining the use of bitmasks.

p.s. re-reading my own comments confuses me.
Glad you got it working! Guess I need stronger glasses to see through your clearer, , LOL
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.