diff options
Diffstat (limited to 'files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html')
| -rw-r--r-- | files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html | 141 |
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 >>> 16) & 0xffff; + var aLo = a & 0xffff; + var bHi = (b >>> 16) & 0xffff; + var bLo = b & 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) << 16) >>> 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 & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001 + // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ + var result = (opA & 0x003fffff) * opB; + // 2. We can remove an integer coersion from the statement above because: + // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001 + // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ + if (opA & 0xffc00000 /*!== 0*/) result += (opA & 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> |
