8

有没有人遇到过关于 int 和 uint 算术如何在 Actionscript 3 中工作的权威规范?(“权威”是指“来自 Adob​​e”或“已被 Adob​​e 宣布为权威”)。特别是我正在寻找一种受支持的方式来进行整数乘法模 2 32。这在我能找到的任何 Adob​​e 文档中都没有涉及。

Actionscript 声称基于 ECMAScript,但 ECMAScript 根本不做整数运算。它在 IEEE-754 上执行所有操作加倍,并在按位运算之前将结果模 2 32减少,这在大多数情况下模拟整数运算。但是,这不适用于乘法:乘法的真实结果,例如 0x10000001 * 0x0FFFFFFF 对于双精度数的尾数来说太长了,因此如果严格遵守规范,低位将丢失。

现在输入 Actionscript。我通过实验int发现,将两个或变量相乘uint并立即将产品转换为intuint似乎总是给我确切的结果。但是,生成的 AVM2 字节码只包含一个普通的“mul”指令,没有直接指示它应该产生一个整数结果而不是浮点结果;虚拟机必须向前看才能发现这一点。我担心我只是在实验中很幸运,并且获得了额外的精度作为奖励,而不是我可以依赖的东西。

(一方面,我的实验都是使用 x86 Flash 播放器进行的。也许它代表英特尔 80 位加倍的中间结果,或者将 64 位 int 存储在评估堆栈上,直到知道它将用于什么。两者都没有在没有本机 32×32→64 乘法指令的非 x86 平板电脑上很容易实现,所以 VM 可能只是决定将精度降低到 ECMAScript 标准指定的精度吗?)

24 小时状态: Mike Welsh 进行了一些有能力的调查并提供了非常有用的链接,但不幸的是还不足以关闭问题。还有谁?

(tl;博士评论中的辩论:whitequark 在某种程度上驳斥了我的假设原因之一,为什么答案可能是“否”。他的观点是有道理的,但当然不构成答案是“是”的证明)。

4

1 回答 1

4

ActionScript 3 基于 ECMAScript 4,其中包括真正的 32 位 int 和 uint 操作。例如,该multipy_i指令执行整数乘法(来源:AVM2 概述)。

不幸的是,Adobe AS 编译器似乎只执行这些操作码的浮点版本,例如multiply,它假定将操作数转换为 64 位浮点数。这可能与ECMAScript 规范一致,该规范规定在数学运算期间 int 将被提升为双精度数以处理溢出。如果它确实做了 64 位浮点乘法,然后转换回 int,那么应该会损失精度。

尽管如此,Flash Player 在立即转换回 int 时似乎不会丢失精度。例如:

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

即使此代码发出一条multiply指令,它也会在 Flash Player 中追踪到 1,这是在没有精度损失的情况下的结果。目前尚不清楚这种行为是否一致且跨平台。但是,我在几个平台的Flash Player中测试了它,包括几部手机,结果似乎始终为1。但是,在解释模式下通过Tamarin shell运行此代码会输出 0!(JIT 模式仍然输出 1,所以这种行为一定是 JIT 的副作用)。所以依赖这个可能是有风险的。

改用multiply_i操作码应该表现得适当。Haxe将在使用整数时使用此操作码。设备也可用于应用此操作码。

于 2011-08-07T17:22:48.677 回答