0

Original question changed.

I want to bitwise turn off the left most bit of a Short value (&H8000) and leave the other bits as they are.

Dim x = BitConverter.GetBytes(Short.MaxValue Or &H8000)
Dim z = BitConverter.ToInt16(x, 0)

Isn't there any shorter way with bitwise operators?

When I do

Dim a = Short.MaxValue Or &H8000

I get a compiler error, cuz it goes up, instead of negating it.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632

2 Answers2

3

That's because .NET uses two's complement, not signed magnitude. To negate, you have to flip all the bits and then add one.

Please just use the unary minus. Please...Pretty please.

EDIT: If for some strange reason you had to do this with bitwise operations, you would have to do this:

Dim somewhatCorrect = (Short.MaxValue xor Short.MinValue) + 1;

which of course is still not bitwise because two's complement negation cannot be done efficiently with bitwise operators.

EDIT2: And here's an unary minus:

Dim correct = -Short.MaxValue;

EDIT3: In response to edited question:

Dim x As Short = 42
Dim xWithHighBitOn = x Or Short.MinValue
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • So, is there a way to do that with operator or not? I just want to make the above less robust – Shimmy Weitzhandler Jul 08 '10 at 00:38
  • Explain how can I perform your please since I am not the big bitwise operator – Shimmy Weitzhandler Jul 08 '10 at 00:39
  • @Shimmy: No. You cannot negate a number using `OR` or `XOR`. You must *bitwise invert* the number and then add one to negate it. – Billy ONeal Jul 08 '10 at 00:39
  • 3
    @Shimmy: I'm saying **don't do this with a bitwise operator**. – Billy ONeal Jul 08 '10 at 00:40
  • y, cuz then it will be more operations and convert to int? i just wanna know – Shimmy Weitzhandler Jul 08 '10 at 00:46
  • and what's the unary- thingy you talked about – Shimmy Weitzhandler Jul 08 '10 at 00:47
  • @Shimmy: You want to make it _less_ robust? If you mean _more_ robust, use the `unary minus`. – codekaizen Jul 08 '10 at 00:48
  • @Shimmy: No, because two's complement negation requires an add operation. You have to add one and there's no efficient bitwise operator to do that. – Billy ONeal Jul 08 '10 at 00:48
  • oh, i made some research in what means one's complement, now i understand the first part, now going to make a research on the unary minus, unless you teach me – Shimmy Weitzhandler Jul 08 '10 at 00:49
  • i tried what u said but the numbers are not as expected, i want that if the given value (Short.MaxValue in the example) is 0, it should become 0x8000, like in my example, your example returns 0x8001. pretty please help me out – Shimmy Weitzhandler Jul 08 '10 at 00:55
  • @codekaizen, you just say what i should or shouldn't do, but im also trying to learn meanwhile, so please explain a bit – Shimmy Weitzhandler Jul 08 '10 at 00:59
  • @Shimmy: You are incorrect. 0x8001 is the correct answer here -- this demonstrates why it's possible to represent a larger negative number than a positive number in two's complement. The reason for the added 1 is so that you don't have to deal with positive and negative zero. Read http://en.wikipedia.org/wiki/Two's_complement for more details. – Billy ONeal Jul 08 '10 at 01:01
  • @Shimmy: If we were dealing with one's complement, 0x8000 would be the correct answer. – Billy ONeal Jul 08 '10 at 01:02
  • try my example from above passing instead Short.MaxValue the value 0. maybe I was wrong saying I want to negate, I want to turn the leftmost bit (0x8000) on and leave the rest as they are, maybe I didn't represent my answer the right way, I do apologize for it. Will edit now. – Shimmy Weitzhandler Jul 08 '10 at 01:02
  • Fix for the wikipedia link from above: http://en.wikipedia.org/wiki/Two%27s_compliment, update and I'll delete this comment – Shimmy Weitzhandler Jul 08 '10 at 01:06
  • Actually I do want the result of the code above, the question is if I can do it with operators rather than code, and actually now my question wen over to the educational part, cuz even i will at last use my example, i have learnt something from you on the way, and thanks for all the info spreading here, honestly, i haven't dealt with binary too much :( it's about time – Shimmy Weitzhandler Jul 08 '10 at 01:11
  • @Shimmy: If you want to flip all the bits, rather than negate the value, just use `Not`. – Billy ONeal Jul 08 '10 at 01:19
  • No, I just want to set the leftmost bit (0x8000) to 1 and leave the other in peace, just like my example above (I do want to do a bitwise operation in a two's complement manner, while not exceeding 16 bit (short), or let's not follow these since im not sure i got the complement stuff yet), and btw billy, thanks for your effort. – Shimmy Weitzhandler Jul 08 '10 at 01:27
  • No, it's not, look at my example above, I want to have my example made with operators, that's all. – Shimmy Weitzhandler Jul 08 '10 at 01:38
  • @Shimmy: Why not just write in the literal 0x8000 then? MyValue or 0x8000. – Billy ONeal Jul 08 '10 at 02:15
  • Cuz then it causes an arithmatic exception, that's exactly what im trying to do and the reason im here burning my night... – Shimmy Weitzhandler Jul 08 '10 at 02:21
  • @Shimmy: I don't see how Short.MaxValue comes into play here in what you've posted though. Short.MaxValue should be 0x8FFF. I've edited my answer once again to match your question now. – Billy ONeal Jul 08 '10 at 02:23
  • maybe you're right, in my actual program i don't let in more than 0x7FFF to the function, so i control the negation or whatever you call it, anyway im retiring, thanks a lot for your time, i did learn some stuff, anyway meanwhile im using the code i posted above and works great, if you'll find an 'operator' way, please post. Thanks! – Shimmy Weitzhandler Jul 08 '10 at 02:25
  • lol, Edit3 is what i looked for so badly :( so simple... thanks finally – Shimmy Weitzhandler Jul 08 '10 at 10:09
1

Two's complement

Dim testV As Short = &HD555S 'a test value

Dim twosC As Short 'twos comp

twosC = (testV Xor &HFFFFS) + 1S 'reverse the bits, add 1

Change most significant bit

twosC = twosC Xor &H8000S
dbasnett
  • 11,334
  • 2
  • 25
  • 33