UNPKG

@stdlib/array

Version:
146 lines (133 loc) 4.58 kB
/** * @license Apache-2.0 * * Copyright (c) 2024 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; // MODULES // var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; var isInteger = require( '@stdlib/math/base/assert/is-integer' ); var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' ); var isComplexLike = require( '@stdlib/assert/is-complex-like' ); var PINF = require( '@stdlib/constants/float64/pinf' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var FLOAT32_SMALLEST_SUBNORMAL = require( '@stdlib/constants/float32/smallest-subnormal' ); // eslint-disable-line id-length var FLOAT32_MAX_SAFE_INTEGER = require( '@stdlib/constants/float32/max-safe-integer' ); var FLOAT32_MIN_SAFE_INTEGER = require( '@stdlib/constants/float32/min-safe-integer' ); var INT8_MIN = require( '@stdlib/constants/int8/min' ); var INT16_MIN = require( '@stdlib/constants/int16/min' ); var INT32_MIN = require( '@stdlib/constants/int32/min' ); var UINT8_MAX = require( '@stdlib/constants/uint8/max' ); var UINT16_MAX = require( '@stdlib/constants/uint16/max' ); var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); // FUNCTIONS // /** * Returns the minimum floating-point array data type of the closest "kind" necessary for storing a provided scalar. * * @private * @param {number} value - real value * @returns {string} array data type */ function minFloatDataType( value ) { if ( value !== value || value === PINF || value === NINF ) { return 'float32'; } if ( isInteger( value ) ) { if ( value >= FLOAT32_MIN_SAFE_INTEGER && value <= FLOAT32_MAX_SAFE_INTEGER ) { // eslint-disable-line max-len return 'float32'; } return 'float64'; } // Assume that if we are provided a tiny value, we don't want to underflow to zero by storing as `float32`... if ( value > -FLOAT32_SMALLEST_SUBNORMAL && value < FLOAT32_SMALLEST_SUBNORMAL ) { return 'float64'; } // Any number which reaches this point is less than the maximum single-precision floating-point number, as floating-point format supports a limited number of decimals (e.g., (1.0+EPS)*10**15 => 1000000000000000.2, which is less than ~3.4e38)... return 'float32'; } // MAIN // /** * Returns the minimum array data type of the closest "kind" necessary for storing a provided scalar value. * * @param {*} value - scalar value * @returns {string} array data type * * @example * var dt = minDataType( 3.141592653589793 ); * // returns 'float32' * * @example * var dt = minDataType( 3 ); * // returns 'uint8' */ function minDataType( value ) { if ( !isNumber( value ) ) { if ( isBoolean( value ) ) { return 'bool'; } if ( isComplexLike( value ) ) { if ( minFloatDataType( value.re ) === 'float64' || minFloatDataType( value.im ) === 'float64' ) { return 'complex128'; } return 'complex64'; } return 'generic'; } if ( value !== value || value === PINF || value === NINF ) { return 'float32'; } if ( isInteger( value ) ) { if ( value === 0 && isNegativeZero( value ) ) { return 'float32'; } if ( value < 0 ) { if ( value >= INT8_MIN ) { return 'int8'; } if ( value >= INT16_MIN ) { return 'int16'; } if ( value >= INT32_MIN ) { return 'int32'; } return 'float64'; } if ( value <= UINT8_MAX ) { return 'uint8'; } if ( value <= UINT16_MAX ) { return 'uint16'; } if ( value <= UINT32_MAX ) { return 'uint32'; } return 'float64'; } // Assume that if we are provided a tiny value, we don't want to underflow to zero by storing as `float32`... if ( value > -FLOAT32_SMALLEST_SUBNORMAL && value < FLOAT32_SMALLEST_SUBNORMAL ) { return 'float64'; } // Any number which reaches this point is less than the maximum single-precision floating-point number, as floating-point format supports a limited number of decimals (e.g., (1.0+EPS)*10**15 => 1000000000000000.2, which is less than ~3.4e38)... return 'float32'; } // EXPORTS // module.exports = minDataType;