9

Is there a direct way how to turn a negative number to positive using bitwise operations in Actionscript 3? I just think I've read somewhere that it is possible and faster than using Math.abs() or multiplying by -1. Or am I wrong and it was a dream after day long learning about bytes and bitwise operations?

What I saw was that bitwise NOT almost does the trick:

// outputs: 449
trace( ~(-450) );

If anyone find this question and is interested - in 5 million iterations ~(x) + 1 is 50% faster than Math.abs(x).

Rihards
  • 10,081
  • 14
  • 55
  • 77
  • 1
    abs is not the same as NOT + 1, abs unsigns, NOT + 1 negates. So if you pass in a positive number youll get different results. – ekerner Aug 26 '17 at 01:21

6 Answers6

16

You need to add one after taking the bitwise negation. This is a property of two's complement number system. It is not related to Actionscript (aside from the alleged performance difference).

So, (~(-450)+1) gives 450
and (~(450)+1) gives -450.

As noted in comments, this answer is written in response to the question, to fix a minor issue in the question asker's experiment. This answer is not an endorsement of this technique for general software development use.

rwong
  • 5,936
  • 1
  • 21
  • 46
10

Use the rule that says

~(x) = (-x)-1
Ray Toal
  • 82,964
  • 16
  • 166
  • 221
  • It probably goes without saying that simple algebra gets you to the formula you wanted, namely `-x = ~x+1` but a good thing to add is that this trick only works for pure integers, and for the smallest possible integer, call it `z`, you actually get back `z` itself, because of the way integers are represented in what is called "twos complement." So make sure you are doing this for in-range integers only. – Ray Toal Jul 16 '11 at 18:31
  • is BitWise better performance than "number = (number < 0 ? -number : number);" in this negating case? – Kanagavelu Sugumar Oct 12 '15 at 06:42
  • The expression `number = (number < 0 ? -number : number)` computes the absolute value, while `number = ~number + 1` negates a value. They are two different operations. As for performance, it depends on how the two expressions are compiled. Generally speaking a test like the one you have can lead to [branch prediction fails](http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array) and there are super nice compiler optimizations to get around it. But why compare? These are two different operations. – Ray Toal Oct 12 '15 at 14:02
5

If two-complement is being used (usually the case), negation is complement then add 1:

-x == ~x + 1

Whether it's faster depends on what optimisations the compiler performs. When in doubt, test.

MRAB
  • 19,740
  • 5
  • 38
  • 31
2

Negation is an operator all unto itself, the unary - operator. Using this is just as fast as using bitwise operations and saves you a lot of typing.

negativeX = -positiveX; // is the same as (~positiveX) + 1

No multiplication is performed.

If speed is your need, and you don't know if the number is negative or positive, the ternary operator ?: is faster than introducing the function-call overhead of Math.abs().

positiveX = unknownX < 0 ? -unknownX : unknownX;
fuzzyTew
  • 3,105
  • 25
  • 23
  • "the ternary operator ?: is faster than introducing the function-call overhead of Math.abs()" Have you actually tested this? `Math.abs` might avoid an extra branching. – Solomon Ucko Mar 07 '20 at 19:46
  • Note the answer was made in 2011, and there has been significant javascript interpreter development since. My personal experience is that function calls are _severely_ slower than anything else. Most of this experience is from many years ago. – fuzzyTew Mar 09 '20 at 04:40
0

Basically numbers 2' complement is the number in opposite sign.

if (num < 0) {
   PosNum = ~num + 1;
}
else {
   NegNum = ~num + 1;
}
Ankit Kotak
  • 315
  • 3
  • 11
-2

Try this:

var number:Number = 10;
//Makes a number
trace(number)
//Tells you the number BEFORE converting
number = number - number * 2;
//Converts number
// Takes number times 2 and subtracts it from original number
trace(number);
//Tells you the number AFTER converting

In the end, all you need is this:

var number:Number = 10;
number = number - number * 2;
Howzieky
  • 819
  • 7
  • 17