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,241
  • 14
  • 58
  • 78
  • 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

18

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
  • 6,062
  • 1
  • 23
  • 51
10

Use the rule that says

~(x) = (-x)-1
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • 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
  • 20,356
  • 6
  • 40
  • 33
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,511
  • 29
  • 24
  • "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
  • 383
  • 4
  • 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
  • 829
  • 7
  • 18