aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/math/imul
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/global_objects/math/imul
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/global_objects/math/imul')
-rw-r--r--files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html141
1 files changed, 141 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html
new file mode 100644
index 0000000000..67da70040d
--- /dev/null
+++ b/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html
@@ -0,0 +1,141 @@
+---
+title: Math.imul()
+slug: Web/JavaScript/Reference/Global_Objects/Math/imul
+translation_of: Web/JavaScript/Reference/Global_Objects/Math/imul
+---
+<div>{{JSRef("Global_Objects", "Math")}}</div>
+
+<div>该函数将两个参数分别转换为 32 位整数,相乘后返回 32 位结果,类似 C 语言的 32 位整数相乘。</div>
+
+<div>
+<p>{{EmbedInteractiveExample("pages/js/math-imul.html")}}</p>
+</div>
+
+<h2 id="语法">语法</h2>
+
+<pre class="syntaxbox"><code>var<em> product</em> = Math.imul(a, b)</code></pre>
+
+<h3 id="Parameters" name="Parameters">参数</h3>
+
+<dl>
+ <dt><code>a</code></dt>
+ <dd>被乘数.</dd>
+ <dt><code>b</code></dt>
+ <dd>乘数.</dd>
+</dl>
+
+<h3 id="返回值">返回值</h3>
+
+<p>类似 C 语言 32 位整数相乘的结果。</p>
+
+<h2 id="描述">描述</h2>
+
+<p><code>Math.imul()</code> 可以进行类似 C 语言的 32 位整数相乘。该特性对于一些项目比如 <a href="http://en.wikipedia.org/wiki/Emscripten" title="http://en.wikipedia.org/wiki/Emscripten">Emscripten</a> 很有用。因为 <code>imul()</code> 是 <code>Math</code> 的静态方法,所以用法是  <code>Math.imul()</code>,而不是新创建的 <code>Math</code> 对象的方法(<code>Math</code> 不是构造函数)。如果使用 JavaScript 浮点数做为 <code>imul</code> 的参数,会有性能损失。这是因为相乘前 imul 会将浮点数转换为整数,相乘后会将整数重新转换为浮点数,这两步转换的开销是比较大的。imul 存在的原因是在 AsmJS(目前为止唯一一种环境)下它是快速的。AsmJS 使 JIST-optimizers 更容易实现 JavaScript 内部的整数。现代浏览器中,唯一能体现出 imul 性能优越的场景是两个 Number 内部以整数的形式相乘(仅在 AsmJS 下可行)。</p>
+
+<h2 id="例子">例子</h2>
+
+<pre class="brush: js">Math.imul(2, 4) // 8
+Math.imul(-1, 8) // -8
+Math.imul(-2, -2) // 4
+Math.imul(0xffffffff, 5) //-5
+Math.imul(0xfffffffe, 5) //-10
+</pre>
+
+<h2 id="Polyfill">Polyfill</h2>
+
+<p>下面的 JavaScript 代码可以实现该函数:</p>
+
+<pre class="brush: js"><span style='background-color: transparent; font-family: consolas,"Liberation Mono",courier,monospace; font-size: 1rem; font-weight: inherit; letter-spacing: -0.00278rem; white-space: pre;'>if (!Math.imul) Math.imul = function(a, b) {</span>
+ var aHi = (a &gt;&gt;&gt; 16) &amp; 0xffff;
+ var aLo = a &amp; 0xffff;
+ var bHi = (b &gt;&gt;&gt; 16) &amp; 0xffff;
+ var bLo = b &amp; 0xffff;
+ // the shift by 0 fixes the sign on the high part
+ // the final |0 converts the unsigned value into a signed value
+ return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) &lt;&lt; 16) &gt;&gt;&gt; 0) | 0);
+};</pre>
+
+<p>然而,下面的实现性能会更好一些。因为运行这段 polyfill 的浏览器很有可能会在内部使用浮点数,而不是整数表示 javascript 的 Number。</p>
+
+<pre class="brush: js"><span style='background-color: transparent; font-family: consolas,"Liberation Mono",courier,monospace; font-size: 1rem; font-weight: inherit; letter-spacing: -0.00278rem; white-space: pre;'>if (!Math.imul) Math.imul = function(opA, opB) {</span>
+ opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
+ // floating points give us 53 bits of precision to work with plus 1 sign bit
+ // automatically handled for our convienence:
+ // 1. 0x003fffff /*opA &amp; 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001
+ // 0x1fffff7fc00001 &lt; Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
+ var result = (opA &amp; 0x003fffff) * opB;
+ // 2. We can remove an integer coersion from the statement above because:
+ // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001
+ // 0x1fffffff800001 &lt; Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
+ if (opA &amp; 0xffc00000 /*!== 0*/) result += (opA &amp; 0xffc00000) * opB |0;
+ return result |0;
+};</pre>
+
+<h2 id="规范">规范</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Specification</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-math.imul', 'Math.imul')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+
+
+
+
+<h2 id="浏览器兼容性">浏览器兼容性</h2>
+
+<p>{{ CompatibilityTable() }}</p>
+
+<div id="compat-desktop">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Firefox (Gecko)</th>
+ <th>Chrome</th>
+ <th>Internet Explorer</th>
+ <th>Opera</th>
+ <th>Safari</th>
+ </tr>
+ <tr>
+ <td>Basic support</td>
+ <td>{{ CompatGeckoDesktop("20") }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div id="compat-mobile">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Firefox Mobile (Gecko)</th>
+ <th>Android</th>
+ <th>IE Mobile</th>
+ <th>Opera Mobile</th>
+ <th>Safari Mobile</th>
+ </tr>
+ <tr>
+ <td>Basic support</td>
+ <td>{{ CompatGeckoMobile("20") }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ <td>{{ CompatUnknown() }}</td>
+ </tr>
+ </tbody>
+</table>
+</div>