main.js (2378B)
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 reldiff = require( './../../../../base/utils/relative-difference' ); 24 var isnan = require( './../../../../base/assert/is-nan' ); 25 var PINF = require( '@stdlib/constants/float64/pinf' ); 26 var MAX_FLOAT64 = require( '@stdlib/constants/float64/max' ); 27 var EPS = require( '@stdlib/constants/float64/eps' ); 28 29 30 // VARIABLES // 31 32 var MAX_DIFF = MAX_FLOAT64 * EPS; 33 34 35 // MAIN // 36 37 /** 38 * Computes the relative difference in units of double-precision floating-point epsilon. 39 * 40 * @param {number} x - first number 41 * @param {number} y - second number 42 * @param {(string|Function)} [scale='max-abs'] - scale function 43 * @returns {number} relative difference in units of double-precision floating-point epsilon 44 * 45 * @example 46 * var d = epsilonDifference( 12.15, 12.149999999999999 ); // => ~0.658ε 47 * // returns ~0.658 48 * 49 * @example 50 * var d = epsilonDifference( 2.4341309458983933, 2.4341309458633909, 'mean-abs' ); // => ~64761.5ε => ~1.438e-11 51 * // returns ~64761.5 52 * 53 * @example 54 * function scale( x, y ) { 55 * // Return the minimum value: 56 * return ( x > y ) ? y : x; 57 * } 58 * 59 * var d = epsilonDifference( 1.0000000000000002, 1.0000000000000100, scale ); // => ~44ε 60 * // returns ~44 61 */ 62 function epsilonDifference( x, y, scale ) { 63 var d = reldiff( x, y, scale || 'max-abs' ); 64 65 // If `d` is `NaN` or `+infinity`, nothing we can do... 66 if ( isnan( d ) || d === PINF ) { 67 return d; 68 } 69 // If `d >= MAX_VALUE`, we will overflow, as `EPS <<< 1`. To prevent overflow, we cap out at the maximum double-precision floating-point number... 70 if ( d >= MAX_DIFF ) { 71 return MAX_FLOAT64; 72 } 73 // Return the answer to the question: how many EPS increments is the relative difference? 74 return d / EPS; 75 } 76 77 78 // EXPORTS // 79 80 module.exports = epsilonDifference;