Features of the mql5 language, subtleties and tricks - page 304

 
amrali #:

No explanation!

The bug (?!) shows in the intermediate results ONLY (for all bitwise operators).

However, assignment (Num >>= 1) works as expected, (luckily).

All integral sub-types of int are processed internally as int.
 
Alain Verleyen #:
All integral sub-types of int are processed internally as int.
It seems that.. thanks Alain for the explanation.
 
Alain Verleyen #:
All integral sub-types of int are processed internally as int.

The bitwise operators promote small integers (such as char/uchar) to signed ints.  https://stackoverflow.com/a/28142065

The integral promotions of small integers do have side effects to be aware of. In the next example, the uchar/char value can be left shifted more than its width (<< more than 8-bits)

#define PrintExpr(A) Print(#A + " = ", (A), " ["+typename(A)+"]")

void OnStart()
{
  PrintExpr((uchar   (1)) << 15);      // = 32768 [int]
  PrintExpr((ushort  (1)) << 15);      // = 32768 [int]
  PrintExpr((char    (1)) << 15);      // = 32768 [int]
  PrintExpr((short   (1)) << 15);      // = 32768 [int]
}

There also another issue with bitwise operators (Signed types):

When doing bitwise operations, if you want strictly well-defined (according to the standard) results, you generally have to ensure that the values being operated on are unsigned. You can do that either with explicit casts, or by using explicitly unsigned constants (U-suffix) in binary operations.

 
Alain Verleyen #:
All integral subtypes of int are treated internally as int.

Thanks.

 
Apparently because it happens in the 32-bit registers of the processor.
 
  PrintExpr((uchar)   (1 << 15));      // = 0 [uchar]
  PrintExpr((ushort)  (1 << 15));      // = 32768 [ushort].
  PrintExpr((char)    (1 << 15));      // = 0 [char]
  PrintExpr((short)   (1 << 15));      // = -32768 [short]
 
amrali #:

The bitwise operators promote small integers (such as char/uchar) to signed ints.  https://stackoverflow.com/a/28142065

The integral promotions of small integers do have side effects to be aware of. In the next example, the uchar/char value can be left shifted more than its width (<< more than 8-bits)

There also another issue with bitwise operators (Signed types):

When doing bitwise operations, if you want strictly well-defined (according to the standard) results, you generally have to ensure that the values being operated on are unsigned. You can do that either with explicit casts, or by using explicitly unsigned constants (U-suffix) in binary operations.

It's probably better to avoid bitwise operations with char/uchar or short/ushort.

Why would you want to do that anyway ?

If you want to use bits to represent Tick data, just count how much bits you need and use enough int (or long ?) to match them. I don't have time to do it, but could be interesting.

 
fxsaber #:
Such a task.

Here https://www.mql5.com/en/forum/349798/page3#comment_57408237

Forum on trading, automated trading systems and testing trading strategies

Scripts: TickCompressor

amrali, 2025.07.04 02:54

TickCompressor v.0.1c: totally eliminated loss of precision by using fixed-point arithemtic (int) encoding for tick prices. (idea here from fxsaber)


Scripts: TickCompressor
Scripts: TickCompressor
  • 2025.07.02
  • fxsaber
  • www.mql5.com
Articles, Library comments: Scripts: TickCompressor
Files:
 
amrali #:

Here https://www.mql5.com/en/forum/349798/page 3#comment_57408237

Try measuring the criterion for the effectiveness of your edits (taken from here).

// Returns the size of the array in bytes.
template <typename T>
ulong GetSize( const T &Array[] ) { return((ulong)sizeof(T) * ArraySize(Array)); }

// Compression format performance criterion.
template <typename T1, typename T2>
double Criterion( const T1 &Decompression[], const T2 &Compression[], const ulong Interval )
{
  const double Performance = (double)ArraySize(Decompression) / Interval;
  
  return(Performance * ((double)GetSize(Decompression) / GetSize(Compression)));
}
TicksShort
TicksShort
  • 2025.07.04
  • www.mql5.com
Короткий формат хранения тиков.
 
fxsaber bitwise operations.


Why does a bitwise operation lead to the creation of an int-variable?

How to do bitwise operations cheaply?


Is it the right thing to do?


Uploaded to this thread as it is autotranslate.

Learn the pluses and smile)))))))

https://en.cppreference.com/w/cpp/language/operator_arithmetic.html

Section Built-in bitwise shift operators
There we read:

  1. Integral promotions are performed on both operands.
  2. In the remaining description in this section, "operand(s)",a, b ,lhs and rhs refer to the converted or promoted operand(s).
  3. The type of the result is that of lhs.