It is not a bug, it is a rule (the same present in java). If you shift an int, only the lowest 5 bits of the shift-by parameter will be used, and because 32 = 100000, it is 0. In java, there is a long type with 64 bits, and its shifting parameter will be cut to 6 bits.
2012.04.24 08:10:54 TEST_Bitwise_Shift_1 #FDXM2,M5: Alert: n<<36 : FFFFFFF0 2012.04.24 08:10:54 TEST_Bitwise_Shift_1 #FDXM2,M5: Alert: n<<4 : FFFFFFF0
It is not a bug, it is a rule (the same present in java). If you shift an int, only the lowest 5 bits of the shift-by parameter will be used, and because 32 = 100000, it is 0. In java, there is a long type with 64 bits, and its shifting parameter will be cut to 6 bits.
Sorry, doesn't behave as described in the documentation at https://book.mql4.com/basics/expressions:
The binary representation of x is shifted by y places to the right. This right shift is logical, it means that all places emptied to the left will be filled with zeros.
x = x >> y; |
The binary representation of x is shifted by y places to the left; the emptied places to the left will be filled with zeros.
x = x << y; |
Where is that "lowest 5 bits of the shift-by parameter" rule stated ?
It is not a bug, it is a rule (the same present in java). If you shift an int, only the lowest 5 bits of the shift-by parameter will be used, and because 32 = 100000, it is 0. In java, there is a long type with 64 bits, and its shifting parameter will be cut to 6 bits.
What has Java to do with mql4? Its a totally different language, its not even remotely similar.
If it is a rule then it should be mentioned in the documentation. The real reason why this happens is because x86 assembly has *undefined* behavior for shift operands > 31 (some CPUs do it some don't) which is an ugly discontinuity. You have to read the documentation from the manufacturer of the target CPU when writing assembly for a certain CPU. But mql4 is supposed to be a high level language and as such it should
(1) either re-implement it correctly (abstracting away the shortcomings of the underlying machine in all cases)
(2) or explicitly define the allowed range for the operand and and enforce it in order to be able to efficiently translate it to machine code without ever risking to run into the underlying x86 limitation/inconsistency and then document it so that all users who are not fluent in x86 assembly and all its pitfalls will know how it behaves.
It seems Metaquotes chose the latter of these two options but then forgot the most important part, namely to document what they did. Or alternatively (Option 3: "do it like C") they didn't think about all this at all and just reach this ugly x86 nastiness through to the programmer unchanged, assuming the programmer will figure it out on his own.Java and C# chose option 2 but they clearly document the behavior.
Real high level languages that deserve this name usually implement option 1 and as a result they don't have to write any lengthy explanations and excuses into their documentation, instead everything just works as expected.
Thank you erzo and 7bit for your comments.
My MT4 is running on a AMD CPU.
Following AMD documentation General-Purpose and System Instructions, MQL4 behaves as it was using instructions
SHLD Shift Left Double
SHRD Shift Right Double
Those indeed perform a shift_by_bits modulo 32 shift, left or right.
However following AMD documentation Media and Floating-Point Instructions, MMX instructions
PSRLD Packed Shift Right Logical Doublewords
PSLLD Packed Shift Left Logical Doublewords
perform true shift_by_bits shift, left or right, without any modulo as I expect and as mentioned by the MQL4 doc.
Both AMD and MQL4 docs refer to so called "Logical Shift Operators". What does "logical" mean in this context ?
Don't know how Intel processors behave ...
Some housekeeping needed in the MQL4 reference book, don't you think ?
The 32 is a processor limitation.
- A logical right shift preserves the sign, a binary right shift shifts zeros in, and a rotate moves the LSB to the MSB.
a logical right shift 1 1111 1111 1111 1111 1111 1111 1111 1100 1111 1111 1111 1111 1111 1111 1111 1111 1110 -4 -2 a binary right shift 1 1111 1111 1111 1111 1111 1111 1111 1100 0111 1111 1111 1111 1111 1111 1111 1111 1110 -4 2,147,483,646 - Some housekeeping needed in the MQL4 reference book, don't you think ?You just discovered that?
Pardon me asking this, is there any use of bitwise operation in trading ?.
:)
WHRoeder, I checked your logical shift definition and, well, I am puzzled. What you say is not verified, look at this:
int n=0xFEDCBA98; Alert("n : "+ n +" "+IntegerToHexString(n)); Alert("n>>8 : "+ n>>8 +" "+IntegerToHexString(n>>8)); Alert("0xFEDCBA98>>8 : "+ 0xFEDCBA98>>8 +" "+IntegerToHexString(0xFEDCBA98>>8)); Alert("n>>-8 : "+ n>>(-8) +" "+IntegerToHexString(n>>(-8))); Alert("0xFEDCBA98>>-8 : "+ 0xFEDCBA98>>(-8) +" "+IntegerToHexString(0xFEDCBA98>>(-8)));
Result:
n : -19088744 FEDCBA98 n>>8 : 16702650 00FEDCBA 0xFEDCBA98>>8 : -74566 FFFEDCBA n>>-8 : 254 000000FE 0xFEDCBA98>>-8 : -2 FFFFFFFE
The result shows a logical shift with the literal 0xFEDCBA98 and a binary shift with the variable n containing the same value !!
Could it be because that code runs on a 64bits CPU ?
Can someone please check that code on a 32bits CPU and post the result ?
To note negative shift also works but returns the bits overflow for the revert shift ... with the same logical/binary shift issue for literal/variable.
With the binary shift behavior, it looks like n>>bits works as n>>(32 + MathMod(bits,32)) do, whatever 'bits' sign is. (MathMod result is signed)
Also read next reply ...

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Normally a bitwise shift operation of 32 bits gives 0x00000000, all bits being shifted out of the integer.
I've noticed the code
lefts n and m variables unchanged though they should be assigned 0x00000000 !
However
does the job and gives 0x00000000.
This is a bug in my opinion.
Attached TEST_Bitwise_Shift.mq4 code sample for testing.