Целочисленное умножение мод 2³² в Actionscript 3 - PullRequest
8 голосов
/ 07 августа 2011

Кто-нибудь сталкивался с авторитетной спецификацией того, как арифметика для int и uint работает в ActionScript 3?(Под «авторитетным» я подразумеваю либо «исходит от Adobe», либо «был объявлен полномочным Adobe»).В частности, я ищу поддерживаемый способ сделать целочисленное умножение по модулю 2 32 .Это не описано ни в одной документации Adobe, которую мне удалось найти.

Заявления Actionscript основаны на ECMAScript, но ECMAScript вообще не выполняет целочисленную арифметику.Он делает все на IEEE-754 удваивается и уменьшает результат по модулю 2 32 перед побитовыми операциями, что в большинстве случаев имитирует целочисленную арифметику.Однако это не работает для умножения: истинный результат умножения, скажем, 0x10000001 * 0x0FFFFFFF, будет слишком длинным для мантиссы двойного, поэтому биты младшего разряда будут потеряны, если спецификация следует букве.

Теперь введите Actionscript.Я обнаружил экспериментально , что умножение двух int или uint переменных и немедленное приведение продукта к int или uint всегда, кажется, дает мне точный результат.Однако сгенерированный байт-код AVM2 просто содержит простую инструкцию "mul" без прямого указания, что он должен давать целочисленный результат, а не результат с плавающей запятой;виртуальная машина должна смотреть вперед, чтобы выяснить это.Я переживаю, что мне просто повезло в моих экспериментах, и я получил дополнительную точность в качестве бонуса, а не то, на что я могу положиться.

(Во-первых, все мои эксперименты проводились с использованием проигрывателя Flash Player x86)Возможно, он представляет промежуточные результаты в виде удвоения 80-разрядных значений Intel или сохраняет 64-разрядное целое число в стеке оценки, пока не станет известно, для чего он будет использоваться. И то, и другое было бы нелегко сделать на планшете, отличном от x86, без встроенного 32-кратногоИнструкция по умножению 32 → 64, может ли виртуальная машина просто принять решение снизить точность до того, что указано в стандарте ECMAScript?)

24-часовой статус: Майк Уэлш провел некоторое умелое исследование и предоставилОчень полезные ссылки, но, к сожалению, недостаточно, чтобы закрыть вопрос.Кто-нибудь еще?

(tl; dr дебаты в комментариях: whitequark опровергает, в некоторой степени, одну из моих гипотетических причин, почему ответ может быть «нет». Его аргументы имеют свои достоинства, но, конечно,не является доказательством того, что ответ «да»).

1 Ответ

4 голосов
/ 07 августа 2011

ActionScript 3 был основан на ECMAScript 4, который включает в себя истинные 32-битные операции int и uint. Например, инструкция multipy_i выполняет умножение целых чисел (источник: Обзор AVM2 ).

К сожалению, компилятор Adobe AS, похоже, выполняет только плавающие версии этих кодов операций, например multiply, который предположительно отбрасывает операнды как 64-битные числа с плавающей запятой. Возможно, это соответствует спецификациям ECMAScript , в которых говорится, что целые числа будут увеличены до удвоенных значений во время математических операций в случае переполнения дескриптора. Если он действительно выполняет 64-битное умножение с плавающей точкой, а затем преобразует обратно в целое число, то должна быть потеря точности.

Несмотря на это, Flash Player, похоже, не теряет точности при немедленном приведении к int. Например:

var n:int = 0x7FFFFFFF;
var n2:int = n*n;
trace(n2);

Несмотря на то, что этот код выдает инструкцию multiply, он отслеживает 1 во Flash Player, что является результатом отсутствия потери точности. Неясно, является ли это поведение последовательным и кроссплатформенным. Однако я протестировал его во Flash Player на нескольких платформах, в том числе на нескольких мобильных телефонах, и результат, похоже, равнялся 1. Однако при выполнении этого кода через оболочку Tamarin в интерпретированном режиме выдается 0! (В режиме JIT по-прежнему выводится 1, поэтому такое поведение должно быть побочным эффектом JIT). Поэтому полагаться на это может быть рискованно.

Использование кода операции multiply_i должно вести себя соответствующим образом. Haxe будет использовать этот код операции при работе с целыми числами. Аппарат также может быть использован для применения этого кода операции.

...