整数乘法 mod 2³²在动作脚本 3 中

发布于 2024-11-28 11:28:31 字数 1001 浏览 3 评论 0原文

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

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

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

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

24 小时状态:迈克·威尔士(Mike Welsh)做了一些有力的调查并提供了非常有用的链接,但不幸的是还不足以结束问题。还有其他人吗?

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

Has anyone come across an authoritative specification of how arithmetic on int and uint works in Actionscript 3? (By "authoritative" I mean either "comes from Adobe" or "has been declared authoritative by Adobe"). In particular I'm looking for a supported way to do integer multiplication modulo 232. This is not covered in any Adobe documentation I have been able to find.

Actionscript claims to be based on ECMAScript, but ECMAScript does not do integer arithmetic at all. It does everything on IEEE-754 doubles, and reduces the result modulo 232 before bitwise operations, which in most cases simulates integer arithmetic. However, this does not work for multiplication: the true result of a multiplying, say, 0x10000001 * 0x0FFFFFFF will be too long for the mantissa of a double, so the low-order bits will be lost if the specification is followed to the letter.

Now enter Actionscript. I have found experimentally that multiplying two int or uint variables and immediately casting the product to int or uint always seems to give me the exact result. However, the generated AVM2 bytecode just contains a plain "mul" instruction with no direct indication that it is supposed to produce an integer result rather than a floating-point one; the virtual machine would have to look ahead to find this out. I'm worrying that I've just been lucky in my experiments and gotten extra precision as a bonus rather than something I can rely on.

(For one thing, my experiments were all performed using an x86 Flash player. Perhaps it represents intermediate results as Intel 80-bit doubles, or stores a 64-bit int on the evaluation stack until it's known what it will be used for. Neither would be easily possible on a non-x86 tablet with no native 32×32→64 multiplication instruction, so might the VM just decide to reduce the precision to what the ECMAScript standard specifies?)

24-hour status: Mike Welsh has done some able investigation and provided very useful links, but unfortunately not enough to close the question. Anyone else?

(tl;dr debate in comments: whitequark refutes, to some degree, one of my hypothetical reasons why the answer might be "no". His points have merit, but of course don't constitute a showing that the answer is "yes").

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青芜 2024-12-05 11:28:31

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

不幸的是,Adobe AS 编译器似乎只执行这些操作码的浮点版本,例如乘法,据称它将操作数转换为 64 位浮点。这可能符合 ECMAScript 规范,该规范规定整数将是在数学运算期间提升为双精度,以便处理溢出。如果它确实执行 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 在处理整数时将使用此操作码。 Apparat 也可用于应用此操作码。

ActionScript 3 was based on ECMAScript 4, which includes true 32-bit int and uint operations. For example, the multipy_i instruction performs integer multiplication (source: AVM2 Overview).

Unfortunately, the Adobe AS compiler only seems to perform the float versions of these opcodes, e.g. multiply, which supposedly casts the operands as 64-bit floats. This is perhaps in accordance with the ECMAScript specs, which state that ints will be promoted to doubles during math operations in order handle overflow. If it does indeed do 64-bit float multiplication, and then converts back to an int, then there should be a loss of precision.

Despite this, the Flash Player seems to not lose precision when casting back to int immediately. For example:

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

Even though this code emits a multiply instruction, it traces out a 1 in the Flash Player, which is the result if there is no loss of precision. It's unclear whether this behavior is consistent and cross-platform. However, I tested it in the Flash Player on several platforms, including a few mobile phones, and the result seemed to be 1 consistently. However, running this code through a Tamarin shell in interpreted mode outputted a 0! (JIT mode still outputted a 1, so this behavior must be a side effect of JIT). So it may be risky to rely on this.

Using a multiply_i opcode instead should behave appropriately. Haxe will use this opcode when working with ints. Apparat could also be used to apply this opcode.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文