Is there still no bitwise NOT?
BlitzMax Forums/BlitzMax Beginners Area/Is there still no bitwise NOT?
| ||
I have discovered I can so Blah = Blah Xor $FFFFFFFF to do a bitwise not, but I would think I should be able to do a normal bitwise not, like you can in C. I think in C it would go something like Blah = !Blah. Maybe the Boolean Not would work in BlitzMax, but I'm pretty sure it didn't work in other versions of Blitz, so I don't trust it will work here. |
| ||
x=1 x=not x print x |
| ||
Bitwise not is ~ There is a thread elsewhere about the difference between using ~ for not or for xor. If you do: x=1 x=~x print x you'll get a bitwise not of x only if you include a second variable in the operation, it turns it into an xor x=1 y=2 x=x~y print x prints the xor of the two values If you think about it, since ~value is the same as FFFFFFFF xor value, it would be a waste of space for BRL to create a separate specific ! operator. If you want to do something like: a=b + !d do a=b+(~d) put it in brackets. |
| ||
tonyg: That is logical "Not", not bitwise. |
| ||
Angel: Thanks, that works! But you don't need to put it in brackets to use it as in your last example. And I don't think it would be a waste to allow us to use !. It would be one less difference from other languages like C, and it would not confuse people who think it is doing something with xor but they can't figure out what. |
| ||
Isn't ! used for declaring Doubles or something? |
| ||
Binary not: Not Bit Not: ~ binary invert (bitwise not for all bits): value ~ $FF (or how many bytes it has) |
| ||
binary invert (bitwise not for all bits): value ~ $FF (or how many bytes it has) Or just ~value, surely? |
| ||
Yup. And yes, I think ! is used for something more important. Get over it ;-D |
| ||
No ~value does not work ... tried that back when someone asked on the bug board. I would have assumed a similar behavior as well ... |
| ||
Yes, it DOES work.Local value = %111 Print Bin( ~value ) |
| ||
I think he means...Local b:Byte = 0 Print Bin(~b) ' gives -1 (I meant just negative) even though it's unsigned. Print Bin(Byte(~b)) Print Bin(b ~ $FF) Local b:Byte Local i:Int = $FFFFFFFF Print Bin(i ~ (~b)) Print Bin(i ~ (b ~ $FF)) SSwift, What do you mean *still*? ~ has been the bitwise compliment/not since B2D (at least)! |
| ||
Yes if you use binary. But any number is in real a binary so it should work any numeric type without inverting it! If you invert 0 (type Byte) you should get 255 which you do not get as a mather of facts. |
| ||
Bill: Wow. You're right. But where is it in the freaking help file?! I've been coding in Blitz for about five years now, asking for bitwise NOT at times, like when trying to work directly with Windows, and other folks have agreed with me that it was unfortunate it didn't have it, and would offer "solutions" like using subtraction. I ended up solving the problem by simply not using not, and using constants that I inverted manually. I only just found the xor trick the other day. It sure would have been nice if it were documented, or Mark, or someone else in the know would have answered my posts asking for a bitwise not all those times. Sheesh! |
| ||
I think Bin `extends` the variable to an Integer before displaying it? If the uppermost bit in the number is set, it will fill all the upper 24 bits with 1's as well, to represent -1 as an Integer. I had the same thing happen with Hex$() trying to display Double's. As soon as you set the 31st bit it fills the upper 32 bits with 1's, as part of displaying it (original data unchanged). So you're SEEING -1, as 11111111111111111111111111111111, but that's because of the display technique. If you print value Shr 8 you'll notice it's 0 instead of having 8 0's at the top end. And yes, again, it DOES work to do ~value, same as !value |
| ||
I'm sorry I'm wrong. Seems like one of the last SyncMods changed something since the thing was posted in the bugs sorry for that *shutting myself* PS: I'm aware how the 2 complement in PC works ... its part of my education ... |
| ||
And yes, again, it DOES work to do ~value, same as !value Yes, I know. I was the one that showed you (your thread about subtracting 2 unsigned longs). :o)I think you're missing the point I was making (albeit, rather badly)... Local b:Byte = $FF Print b Print ~b ' Should an unsigned variable be represented as being negative? I'd say not. [edit]But It appears that wasn't what Dreamora was going on about anyway...:o)[/edit] |
| ||
That was my point. But the convert to string seems to involve a convert to a different numeric type first. If you enclose the ~b with a byte() it will result in 255 (checked that before the above posting). Its just another of BMs extremely inconsistent handling of situations and operators :( |
| ||
If you enclose the ~b with a byte() it will result in 255 Yeah, I already did that above.It's still wrong IMHO! A byte containing $FF when converted to an int should be $000000FF, not $FFFFFFFF... Local b:Byte Local i:Int = $FFFFFFFF Print i & (~b) ' Shouldn't this be $FFFFFFFF AND $FF (255) ?? 'b' = ~b Print i & b ' Like this?'b' shouldn't be converted to an int before inversion. Am I just talking from my nether regions here? Anyway, after that completely pointless rantette... @Sswift - It's in the docs (for B3D at least), but it *is* well hidden. ;o) Go to 'Language Reference>Expressions'. |
| ||
For some reason you need to cast (~b) to a byte This works Local b:Byte Local i:Int = $FFFFFFFF Print i & Byte(~b) ' $000000FF 'b' = ~b Print i & b ' Like this? |
| ||
I think it is the print statement itself that extends it from byte to Int equivalent, producing the extra bits. Probably when you do ~byte it actually does only invert the 8 bits, but when you PRINT it it prints additional made-up bits. Your byte variable is still only $FF. |
| ||
Local a:Int Local b:Byte b = %100000001 b = ~b Print Bin(b) a = ~b Print Bin(a) I suspect this is the source of the problem. B is getting converted to an int before the NOT is performed, and when you perform the NOT on an int, you get the result you see here. |
| ||
LOL...This is what happens when you try to operate a forum when you're suffering from sleep deprivation. ;oD I know that's what's happening, I just didn't explain it very well. It's definitely not just the print statement... Local b:Byte = 0 Local i2:Int = $FFFFFFFF Local i2:Int = i & ~b Print "'i2' should be 255, it's actually " + i2 Print "Especially for AngelDaniel - " + (i2 Shr 24) i2 = i & Byte(~b) Print i2It's probably not a good idea to be mixing different variable types like this anyway though. I just thought it was worth a mention. I tend to just stick to ints anyway. |
| ||
The operation is wrong It should be Local i2:Int=i~b |
| ||
*sigh*...I give up... 8o/ But, can I have some? |
| ||
In C bitwise xor is the ^ opperator and bitwise not is the ~ character. So BMX just uses the ~ for both because ^ is the exponent opperator. But making ! the bitwise not opperator would be bad because in every other language ! is the logical not. ( The notequal opperator <> should be != but I think it doesn't matter as much.) I was thinking that maybe the Byte type is actually signed, because in C (or at least in the MacOS X gcc implementation) a char is signed: char c = 0xFF; printf("%i\n", c); /* produces -1 */ So that could be explaining why you kept getting some of those problems because Bytes are signed. EDIT: I just tried a small Byte test and got some strange results: Local b1:Byte = $FF Local b2:Byte = ~b1 Print b1 ' produces 255' Print ~b1 ' produces -256' Print b2 ' produces 0' Print ~b2 ' produces -1' Printing b1 made me think that Bytes are unsigned as it printed 255 which is what would be expected in an unsigned byte. But when I printed ~b2 it came as -1 which would be expected in a signed byte! Printing b2 seemed right as it came out to 0, but the strangest one was b1 which came out to -256! -256 cannot be expressed as either a signed or unsigned byte so I'm thinking that what happened was that b1 ( $FF ) was converted to an int ( $000000FF ) and then the bitwise not of that is $FFFFFF00 which is -256. That would explain the b1 which is 255 because if it is $FF then it is converted to an int which is $000000FF which is 255. ~b2 is right because b2 is converted to an int which is $00000000 and the not of that is $FFFFFFFF which is -1. b2 is 0 either way. So in the end, all these problems arrise because everything seems to be converted to an int before any operators are applied in the Print function.And I still don't know whether Bytes are signed or unsigned. |
| ||
If I had BlitzMax, I would prefer they kept away from ! operator, because since you can pump C code inside Max, you might automatically place the ! in the source thinking it was the bitwise not operator, then finding out it goes titties up because it should really be the ~ operator! Que head scratching for a while! :) Dabz |
| ||
Here's what I think is happening. ~ is used to XOR two numbers together. I bet that when you don't specify 2 parameters, BlitzMax will XOR one parameter with a constant, and I bet that constant is $FFFFFFFF. So if you do Local v1:Byte = $FF Print ~v1 What happens is that v1 needs to be converted to an int because the constant is an int. Then v1 is XORed with the constant and the result is returned to Print. So $FF is converted to $000000FF, then XORed with $FFFFFFFF, giving you $FFFFFF00 which is -256. Now when you cast the number to byte, then the top 24 bits are truncated leaving you with $00. So if you did [code] Local v1:Byte = $FF Local v2:Byte = ~v1 Print v2 [code] Then v1 is converted to $000000FF, XORed with $FFFFFFFF leaving you with $FFFFFF00, then converted to byte and assigned to v2, making v2 = $00. It seems the solution is to treat ~ as only an XOR if you're using anything other than ints. So to do a NOT on a byte, just use $FF ~ v1. Now since both sides of the equation are bytes, it'll not do any conversions and give you the correct answer. |
| ||
Ah that would explain why the bytes were mysteriously being converted to Ints and printing out strange and unexpected values. Though I think if you are XORing a byte, even if it is with an implicit constant like it seems to be here, BMX should at least XOR it with a Byte constant and not an Int constant, since v1 is a Byte and not an Int. |
| ||
It should ... thats the problem ... And as worse part it does not even mention that it does this not allowed conversion |