Or… how do you XOR doubles without getting integer results?
I am using Actionscript 3.0 and found the following:
var a:Number = 3.000000004;
var b:Number = 29.999999999;
trace ("a: " + a); //3.000000004
trace ("b: " + b); //29.999999999
a ^= b;
b ^= a;
a ^= b;
trace ("a: " + a); //29
trace ("b: " + b); //3
Clearly, the XOR operation is converting my Numbers into ints. I am a bit surprised by this and don’t exactly understand the reason behind it. But I do know that other bitwise operations will also change Number into int, so I am not that surprised.
Be that as it may, is there a way to XOR doubles (aka Numbers) without having them get truncated to integers? I used the above XOR originally for performance optimization (these number switches are executed millions of times in an array). I assumed if I skipped the temporary variable, I would see a speed increase. Alas, if the Number data gets changed to int, it is all for naught.
Just wondering if there is a solution to this or if I need to give up on XOR in this case.
(ps, I won’t be able to check this thread for a while, but appreciate any suggestions, knowledge, etc. in the meantime)
(pps, in case you are curious, this is the method I am trying to speed up if possible)
public static function reversePairs(values:Vector.<Number>):void {
//1, 2, 3, 4, 5, 6 -> 5, 6, 3, 4, 1, 2
var l:int = values.length;
var n:int = l * 0.5;
n -= n % 2;
for (var a:int = 0; a < n; a++) {
var b:int = (l - a) - 2 * ((a + 1) % 2);
//we cannot use xor because it truncates the decimal value
//values[a] ^= values[b];
//values[b] ^= values[a];
//values[a] ^= values[b];
//we MUST use a temporary variable instead
var c:Number = values[b];
values[b] = values[a];
values[a] = c;
}
}
The xor-swap operation is not an optimization. It’s a pessimization.
It’s hard to think to any architecture in which that would be a good idea (four steps each one depending on the completion of the preceding one even assuming read-modify-write memory to memory as atomic… a truly horrible implementation of swap).
The best way to do an exchange between two values in memory is most often a double-read followed by a double-write:
each of those pairs can also be executed in parallel (the two reads are independent, and also the two writes are independent) so the operation can complete in two steps.
Most optimizing compilers are able to recognize the idiomatic three-steps swap
to generate the two step exhange code for that it this is the best way for the hardware.
That said something “equivalent” for floating point to that bad xor-swap code can be obtained by using inplace subtraction
-=instead of inplace xor^=.It is however a true exchange only if accuracy problems don’t kick in.