Oxygen Basic
Programming => Example Code => General => Topic started by: Arnold on August 06, 2017, 10:53:13 PM
-
Hi Charles,
I had a great break last month. There are too many changes of weather which kill me down a little bit. My editor project is delayed at the moment (but not stalled).
In the meantime I do some exercises which I find at Rosetta Code. There is a task which deals with bitwise operations and this seems to work with Oxygenbasic like in other 32 bit languages. However I am not quite sure when it comes to arithmetic / logical right shift using negative integers (positive numbers give the same result). Is there a better way in Oxygenbasic to get the arithmetic right shift value for negative numbers?
Roland
'Bitwise operations (32 bit)
include "$/inc/console.inc"
print "Bitwise operations (32 bit)" & cr
sub bitwise(int a, b)
printl "a = " + a
printl "b = " + b
printl
printl "a and b = " + a and b
printl "a or b = " + a or b
printl "a xor b = " + a xor b
printl "not a = " + not a
printl "a << b = " + a << b 'left shift
printl "a / (2^b) (arithmetic) = " + floor(a / (2^b)) 'right shift
printl "a >> b (logical) = " + a >> b 'right shift
printl "a <<< b = " + a <<< b 'rotate left
printl "a >>> b = " + a >>> b 'rotate right
printl
end sub
int x, y
sub prompt()
printl "Enter an integer ? " : x = input()
print "Enter another integer ? " : y = input()
end sub
while 1
prompt()
bitwise(x, y)
printl "Another test? (y/n) "
ans = ltrim rtrim input()
if lcase(ans) != "y" then exit while
wend
.
-
Hi Roland,
In assembler sar is the arithmetic counterpart of shr
thus:
int a=-16
sar a,2 'SAR shift arithmetic right
print a '-4
You can also do it in Basic by inverting the bits, but you must first test whether the number is negative:
int a=-16
print not(not(a)>>2) '-4
-
Hi Charles,
would this little function be ok? I get the expected results but I am not sure if I will need a pushad / popad.
function arshift(int d, c)
mov eax, d 'dest
mov ecx, c 'count
sar eax, ecx 'SAR shift arithmetic right
return eax
end function
Using the second (not(not..) approach it seems to me that I only get the logical value for right shift e.g. 536870910 instead of -2 for a=-15, b=3. Am I doing something wrong?
Roland
-
Yes but it can be a little simpler:
the final value of eax is returned by default
cl is the lowest 8 bits of ecx
function arshift( int d, c)
mov eax, d 'dest
mov cl, c 'count
sar eax, cl 'SAR shift arithmetic right
end function
int b=arshift( -16,2)
print b
The not(..) technique is rather contorted and only works on negative integers. You will also need to ensure that it assigns to an int, not a dword, to display the negative value.
obfuscators delight :)
int a=-16
int b
b= ( a>0 ? a>>2 : not(not(a)>>2) )
print b
-
Thank you Charles for your help. Everything works fine now. And I think it is a very nice thing that it is possible now to use the ternary operator ? : with Oxygenbasic too.