Forex Factory (https://www.forexfactory.com/)
-   Platform Tech (https://www.forexfactory.com/forum/69-platform-tech)
-   -   Would like advice and examples of bitwise code to store counts (https://www.forexfactory.com/thread/503612-would-like-advice-and-examples-of-bitwise-code)

pips4life Sep 9, 2014 9:21pm | Post# 1

Would like advice and examples of bitwise code to store counts
 
Hi MQL4 coders,

I have in mind an idea to use a single variable and bitwise operations to keep track of 10 different 2-bit counters. With 2-bits-per-counter, I can store values 0,1,2 or 3. Given that I have 10 different independent counters, I will assign a specific two bits for each counter.

Initially all masterCount bits are 0, of course. Then I will define a function with if/else if/... to determine which counter that I:
1. Read the current count.
2. If <3, add one to the specific counter.
3. Save the new count to the masterCount variable, without changing any of the other existing bits.

As I haven't written any significant bitwise code, I'm not sure the best way to proceed. What's the best way to isolate a given counter? I would assume it's to do an logical AND between the masterCount, and then with all 0's except for two 1's in the position of the specific counter I want.

Then if the value is 0,1, or 2, I want to add one to it, and then store the new 2-bits (but not change the other bits).
Do I logical-AND the masterCount with all 1's, except 0's for the 2-bits I want, and then logical-OR it with my new count-value, bit-shifted of course?

Inserted Code
int addOne (int masterCount, string str)
{
   int count;
 
   if (str == "A")
   {
      count = masterCount & 0x0000003  // no bit shifting needed.  Is this hex correct??
      if (count < 3) count++;
      masterCount = masterCount & all_ones_except_least_two_bits  (Syntax??)
      masterCount = masterCount | (count) // no bit shifting needed
   }
   else if (str == "B")
   {
      count = masterCount & 0x000000C  // next 2-bits, 4+8 = 12 = hex C
      if (count < 3) count++;
      masterCount = masterCount & all_ones_except_SECOND_least_two_bits
      masterCount = masterCount | (count >> 2) // next-2-bits   (OR, << 2 ??? I don't know this part)
   }
   else if (str == "C")
   {
      count = masterCount & 0x0000030 // next 2-bits, 16+32 = 48 = hex 30
      ...
   } ...
 
  
   return(masterCount);
}



Am I on the right track? What's the best way to declare each of the 10 sets of bits, with #define, or just
use the appropriate hex (or binary??) ?

By the way, I intend to save this value to an MT4 GlobalVariable, so that I can pass the information from one chart to all the other charts that read the GVar. It's cleaner to just use one GVar, but if I had to, I suppose I could use 10 separate GVars and avoid bitwise math altogether. The GVars are of type double, but I would think that if I avoid using the decimal, I can use 30, 31 or 32 bits by just setting a long_int to the value I "Get" from the GVar. As I only need 20 bits for now, I would think it should work, unless someone knows otherwise.

Besides some direct suggestions, I'd also welcome a pointer-to or uploads-of some bitwise operations in any .mq4 file that I can look at.

It seems to me another good use of bitwise math would be if I have either some boolean variables, or small int values, that I could combine into one variable, and use that one variable in a function definition. If I want to add a new boolean or small int values, and if I have any unused bits, I can just expand my use of the existing variable, rather than go through all my code to change the function definition and all the calls to it, to update to the new variable(s). Is this true? Or does the use of bitwise math slow things down, because one is always encoding/combining the bits, sending it to the function, and the function must then decode separate the bits to set local variables (bool & int). I'm not sure it's worth it to do this, or if it works the same either way I go, or ...


Thanks in advance for any help/ideas.

Kent (pips4life)

MaxDoom Sep 10, 2014 1:31am | Post# 2

Hi MQL4 coders, I have in mind an idea to use a single variable and bitwise operations to keep track of 10 different 2-bit counters. With 2-bits-per-counter, I can store values 0,1,2 or 3. Given that I have 10 different independent counters, I will assign a specific two bits for each counter. Initially all masterCount bits are 0, of course. Then I will define a function with if/else if/... to determine which counter that I: 1. Read the current count. 2. If <3, add one to the specific counter. 3. Save the new count to the masterCount variable, without...
have a look here

http://www.codeproject.com/Articles/...wise-operators

rockit Sep 10, 2014 6:01am | Post# 3

Am I on the right track? What's the best way to declare each of the 10 sets of bits
I would do this:
Inserted Code
uint mask[10] = {3, 3<<2, 3<<4, 3<<6, 3<<8, 3<<10, 3<<12, 3<<14, 3<<16, 3<<18};
uint one[10] = {1, 1<<2, 1<<4, 1<<6, 1<<8, 1<<10, 1<<12, 1<<14, 1<<16, 1<<18};
uint counter; //bits pair
uint mastercounter = 0;
then access like so:
Inserted Code
mastercounter = /*isolate counter (bits):*/ (((mastercounter & mask[counter])
                     /*add one:*/ + one[counter])
                     /*normalise to 2 bits:*/ & mask[counter])
                     /*add the rest:*/ | (mastercounter & (~(mastercounter & mask[counter])));
or, the more generic version:
Inserted Code
uint counter; //bits pair
uint mastercounter = 0;
// access
mastercounter=(((mastercounter&(3<<(counter*2)))+(1<<(counter*2)))&(3<<(counter*2)))|(mastercounter&(~(mastercounter&(3<<(counter*2)))));

MaxDoom Sep 10, 2014 7:08am | Post# 4

something else you should bear in mind....

the global variables of the terminal can only be of the type double.
So you will need to convert it before and after setting, to an integer for your bitwise usage.
But why not just write a small routine that handles 10 global variables instead?

regards

pips4life Sep 10, 2014 1:20pm | Post# 5

Thanks MaxDoom and rockit. That helped a lot.

Very nice, compact and organized code suggestions, rockit.

MaxDoom, I did mention the double vs. int in my 1st post, but the GVar does convert to int fine for my purposes.

I did also mention that I could use 10 separate global variables -- and I still can -- but is there much of a drawback to combining them into one? Seems like there might be a little overhead to do the bitwise operations, but I don't really know how I would measure it, when we're talking possible milliseconds difference, or even microseconds. Still, when every chart does it, the extra overhead does add up.

I do use a lot of GVars, so I don't like to add too many extras because the list gets cluttered when I need to look at them. In my application, I said I have 10 2-bit counters, which is true, but actually I have 3 sets of 10, so... it's 3 GVars using bitwise, and 30 GVars if I separate them.

So far, using the bitwise approach, my code works great!

I appreciate the help.


© Forex Factory