MLQ4: bit operation in enums

 

Hi,

sorry for the "low level" non obj programming, just an old style C code...

I want to screen through an enum int bit by bit. Here the relevant code:

enum Result_types
  {
   NOTHING =0,
   Short_rev =1,        // Open Long, Close Short
   Long_rev =2,         // Open Short, Close Long
   Close_all =4,        // (1<<2)
   Close_sell =8,       // (1<<3)
   Close_buy =16 ,      // (1<<4)
   Buy_Buy =32,         // (1<<5)
   Buy_Sell =64,        // (1<<6) 
   No_More_Long =128,   // (1<<7)     
   No_More_Short =256,  // (1<<8)
   Trade_Timeout =512,  // (1<<9)
   No_Trades =1024,     // (1<<10

  };

...

               for (int k=0; k < 11; k++)       
                  {
     Result_types temp_R_final = (R_final & (1<<k));            // R_final is also type " Result_types" and contains 
several results = several bits set.
                  if (temp_R_final >0) do_Action(temp_R_final);        
                  }
There may be several bits set at a time, and the action routine has a case statement inside, hence I can call it only w/ 1 bit ON, otherwise the case statements would become too complex.

I have 2 issues w/ this:

1st, I get a compiler warning: "explicit enum conversion"

and it seems only to work for 1 byte, i.e. the bit 0-7.

Help is appreciated.

Regards

hk

 

Forum on trading, automated trading systems and testing trading strategies


Hello,

Please use the SRC button when you post code. Thank you.


This time, I edited it for you.


 

Thank you,


will do [src]!


Any suggestion, how to "find" bits in an integer?

Rgds

hk

 
lve0200:

You may store the bits in an int, and then process them one by one all at the same time, in the correct sequence. This will save you having to implement a loop:


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum Result_types
  {
   NOTHING=0,
   Short_rev =1,        // Open Long, Close Short
   Long_rev =2,         // Open Short, Close Long
   Close_all =4,        // (1<<2)
   Close_sell =8,       // (1<<3)
   Close_buy =16 ,      // (1<<4)
   Buy_Buy =32,         // (1<<5)
   Buy_Sell =64,        // (1<<6) 
   No_More_Long =128,   // (1<<7)     
   No_More_Short =256,  // (1<<8)
   Trade_Timeout =512,  // (1<<9)
   No_Trades =1024,     // (1<<10
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int R_final = Short_rev | Long_rev | Close_buy;
   /*
   for(int k=0; k<11; k++)
     {
      Result_types temp_R_final=(R_final &(1<<k));  
      Print("k: "+k+" value: "+temp_R_final+" enum: "+EnumToString(temp_R_final));         
      if(temp_R_final>0) do_Action(temp_R_final);
     }
  }
  */
  do_Action (R_final);
  }
//+------------------------------------------------------------------+

void do_Action (int flags)
{
   if (flags & Result_types::Short_rev) {
      Print("Short reverse");
   }
   if (flags & Result_types::Long_rev) {
      Print("Long reverse");
   }
   if (flags & Result_types::Close_all) {
      Print("Close all");
   }
   if (flags & Result_types::Close_sell) {
      Print("Close sell");
   }
   if (flags & Result_types::Close_buy) {
      Print("Close buy");
   }
   /*other flags here*/
}

Output:

"Short reverse"

"Long reverse"

"Close buy"

But the sequence has to be in the correct order. We would not want an EA opening an order in one subroutine and closing it in the next.

Use typecasting to remove the compiler warnings "implicit conversion" or "expression not boolean".

 

Hi, thank you, very nice!

I also got my loop/shift bitwise operation to work. I just casted everything to (int), as following. Admittedly a bit a pain in the neck, but it works!

               for (int k=0; k <= 10; k++) 
                  {
     Result_types temp_R_final = (R_final & (Result_types)((int)1<<(int)k));            
                  if (temp_R_final >0) do_Action(temp_R_final);         
                  }