main.js (2404B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 'use strict'; 20 21 // MODULES // 22 23 var isnan = require( './../../../../base/assert/is-nan' ); 24 25 26 // VARIABLES // 27 28 // Define a mask for the least significant 16 bits (low word): 65535 => 0x0000ffff => 00000000000000001111111111111111 29 var LOW_WORD_MASK = 0x0000ffff>>>0; // asm type annotation 30 31 32 // MAIN // 33 34 /** 35 * Performs multiplication of two unsigned 32-bit integers and returns an array of two unsigned 32-bit integers which represents the unsigned 64-bit integer product. 36 * 37 * @param {ArrayLikeObject} [out] - output array 38 * @param {uinteger32} a - integer 39 * @param {uinteger32} b - integer 40 * @returns {ArrayLikeObject} output array 41 * 42 * @example 43 * var v = uimuldw( 0xAAAAAAAA, 0x55555555 ); 44 * // returns [ 954437176, 1908874354 ] 45 */ 46 function uimuldw() { 47 var out; 48 var w1; 49 var w2; 50 var w3; 51 var ha; 52 var hb; 53 var la; 54 var lb; 55 var a; 56 var b; 57 var t; 58 var k; 59 60 if ( arguments.length === 3 ) { 61 out = arguments[ 0 ]; 62 a = arguments[ 1 ]; 63 b = arguments[ 2 ]; 64 } else { 65 out = [ 0, 0 ]; 66 a = arguments[ 0 ]; 67 b = arguments[ 1 ]; 68 } 69 if ( isnan( a ) || isnan( b ) ) { 70 return NaN; 71 } 72 a >>>= 0; // asm type annotation 73 b >>>= 0; // asm type annotation 74 75 ha = ( a >>> 16 ) >>> 0; 76 la = ( a & LOW_WORD_MASK ) >>> 0; 77 78 hb = ( b >>> 16 ) >>> 0; 79 lb = ( b & LOW_WORD_MASK ) >>> 0; 80 81 t = ( la*lb ) >>> 0; 82 w3 = ( t & LOW_WORD_MASK ) >>> 0; 83 k = ( t >>> 16 ) >>> 0; 84 85 t = ( ( ha*lb ) + k ) >>> 0; 86 w2 = ( t & LOW_WORD_MASK ) >>> 0; 87 w1 = ( t >>> 16 ) >>> 0; 88 89 t = ( ( la*hb ) + w2 ) >>> 0; 90 k = ( t >>> 16 ) >>> 0; 91 92 out[ 0 ] = ( ( ha*hb ) + w1 + k ) >>> 0; // compute the higher 32 bits and cast to an unsigned 32-bit integer 93 out[ 1 ] = ( ( t << 16 ) + w3) >>> 0; // compute the lower 32 bits and cast to an unsigned 32-bit integer 94 95 return out; 96 } 97 98 99 // EXPORTS // 100 101 module.exports = uimuldw;