Почему xor усекает числовые значения? - PullRequest
0 голосов
/ 22 декабря 2011

Или ... как вы удваиваете XOR без получения целочисленных результатов?

Я использую Actionscript 3.0 и обнаружил следующее:

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

Очевидно, что операция XOR конвертирует мои числа в целые. Я немного удивлен этим и не совсем понимаю причину этого. Но я знаю, что другие побитовые операции также преобразуют Number в int, поэтому я не удивлен .

Как бы то ни было, есть ли способ удваивать значения XOR (или числа) без их усечения до целых чисел? Первоначально я использовал XOR для оптимизации производительности (эти числовые переключатели выполняются в массиве миллионы раз). Я предположил, что если я пропущу временную переменную, я увижу увеличение скорости. Увы, если данные Number изменяются на int, это все ни к чему.

Просто интересно, есть ли решение для этого или мне нужно отказаться от XOR в этом случае.

(ps, я не смогу проверить эту ветку некоторое время, но пока буду благодарен за любые предложения, знания и т. Д.)

(pps, если вам интересно, это метод, который я пытаюсь ускорить, если это возможно)

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;
    }
}

Ответы [ 2 ]

4 голосов
/ 22 декабря 2011

Операция xor-swap не является оптимизацией. Это пессимизация.

Трудно придумать любую архитектуру, в которой это было бы хорошей идеей (четыре шага каждый в зависимости от завершения предыдущего, даже предполагая, что чтение-модификация-запись памяти в память является атомарной ... действительно ужасная реализация своп).

Лучший способ сделать обмен между двумя значениями в памяти - чаще всего двойное чтение с последующей двойной записью:

reg1 = mem1; reg2 = mem2;
mem1 = reg2; mem2 = reg1;

каждая из этих пар также может выполняться параллельно (две операции чтения являются независимыми, а также две операции записи являются независимыми), поэтому операция может быть завершена в два этапа. Большинство оптимизирующих компиляторов способны распознать идиоматический трехшаговый своп

{ type temp = x; x = y; y = t; }

для генерации двухэтапного кода обмена, для которого это лучший способ для оборудования.

То, что что-то «эквивалентное» для плавающей запятой этому плохому коду xor-swap, можно получить, используя вычитание по месту -= вместо xore ^=.

.

Это, однако, истинный обмен, только если проблемы с точностью не возникают.

1 голос
/ 22 декабря 2011

^= является побитовой операцией, а не целочисленной операцией как таковой (ср., документы Adobe ).Полезно представить, что не существует такого понятия, как целые числа.

На самом деле потребуется несколько больше временных переменных для XOR числа с десятичной дробью, которое не будет решать скоростьпроблема.

Хотя я не могу предложить что-либо, чтобы перезаписать своп, я могу предложить, чтобы вы никогда ( ever! ) не объявляли переменные в цикле for, если в этом нет необходимости.Ergo:

var b:int;
var c:Number;
for (var a:int = 0; a < n; a++) {
  b = (l - a) - 2 * ((a + 1) & 1);
  c = values[b];
  values[b] = values[a];
  values[a] = c;
}

Также обратите внимание, что я изменил модуль на аддитивную маску , используя 1, что должно быть быстрее.

Кроме того, это может быть полезно дляразрешить классу Vector выполнять сортировку и написать собственный метод сортировки для вашего конкретного использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...