time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

flipsign.js (2367B)


      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 toWords = require( '@stdlib/number/float64/base/to-words' );
     24 var getHighWord = require( '@stdlib/number/float64/base/get-high-word' );
     25 var fromWords = require( '@stdlib/number/float64/base/from-words' );
     26 
     27 
     28 // VARIABLES //
     29 
     30 // 10000000000000000000000000000000 => 2147483648 => 0x80000000
     31 var SIGN_MASK = 0x80000000>>>0; // asm type annotation
     32 
     33 // High/low words workspace:
     34 var WORDS = [ 0, 0 ]; // WARNING: not thread safe
     35 
     36 
     37 // MAIN //
     38 
     39 /**
     40 * Returns a double-precision floating-point number with the magnitude of `x` and the sign of `x*y`.
     41 *
     42 * @param {number} x - number from which to derive a magnitude
     43 * @param {number} y - number from which to derive a sign
     44 * @returns {number} a double-precision floating-point number
     45 *
     46 * @example
     47 * var z = flipsign( -3.14, 10.0 );
     48 * // returns -3.14
     49 *
     50 * @example
     51 * var z = flipsign( -3.14, -1.0 );
     52 * // returns 3.14
     53 *
     54 * @example
     55 * var z = flipsign( 1.0, -0.0 );
     56 * // returns -1.0
     57 *
     58 * @example
     59 * var z = flipsign( -3.14, -0.0 );
     60 * // returns 3.14
     61 *
     62 * @example
     63 * var z = flipsign( -0.0, 1.0 );
     64 * // returns -0.0
     65 *
     66 * @example
     67 * var z = flipsign( 0.0, -1.0 );
     68 * // returns -0.0
     69 */
     70 function flipsign( x, y ) {
     71 	var hx;
     72 	var hy;
     73 
     74 	// Split `x` into higher and lower order words:
     75 	toWords( WORDS, x );
     76 	hx = WORDS[ 0 ];
     77 
     78 	// Extract the higher order word from `y`:
     79 	hy = getHighWord( y );
     80 
     81 	// Leave only the sign bit of `y` turned on (if on):
     82 	hy &= SIGN_MASK;
     83 
     84 	// Flip the sign bit of `x` only when the sign bit of `y` is on:
     85 	hx ^= hy; // 1^1=0 (flipped), 0^1=1 (flipped), 1^0=1 (unchanged), 0^0=0 (unchanged)
     86 
     87 	// Return a new value having the same magnitude as `x`, but with the sign of `x*y`:
     88 	return fromWords( hx, WORDS[ 1 ] );
     89 }
     90 
     91 
     92 // EXPORTS //
     93 
     94 module.exports = flipsign;